Finding certain X window with Python's Xlib
The reason why there is no string "urxvt", "URxvt" is that XWindows are in hierrarchy. And for some reason, on my desktop, urxvt windows are not at the first level.
So one must traverse whole tree like this:
from Xlib.display import Display
def printWindowHierrarchy(window, indent):
children = window.query_tree().children
for w in children:
print(indent, w.get_wm_class())
printWindowHierrarchy(w, indent+'-')
display = Display()
root = display.screen().root
printWindowHierrarchy(root, '-')
One line of the (probably quite long) script output is then:
--- ('urxvt', 'URxvt')
Related videos on Youtube
Martin Jiřička
Updated on September 18, 2022Comments
-
Martin Jiřička over 1 year
I am trying to find an unmapped window on my X server in order to map it back and send it some EWMH hint. Because the window is unmapped I cannot use EWMH to ask the window manager directly. So I am trying to get it through Xlib, but I am experiencing problems with it. The whole API is very confusing for me.
I am using Python's Xlib wrapper. Now lets have a look at following Python script:
import subprocess from time import sleep from ewmh import EWMH subprocess.Popen(['urxvt']) # Run some program, here it is URXVT terminal. sleep(1) # Wait until the term is ready, 1 second is really enought time. ewmh = EWMH() # Python has a lib for EWMH, I use it for simplicity here. # Get all windows? windows = ewmh.display.screen().root.query_tree().children # Print WM_CLASS properties of all windows. for w in windows: print(w.get_wm_class())
What is output of the script? One opened URXVT terminal and something like this:
None None None None ('xscreensaver', 'XScreenSaver') ('firefox', 'Firefox') ('Toplevel', 'Firefox') None ('Popup', 'Firefox') None ('Popup', 'Firefox') ('VIM', 'Vim_xterm')
But when I run this command and click on the opened terminal:
$ xprop | grep WM_CLASS WM_CLASS(STRING) = "urxvt", "URxvt"
The same is with WM_NAME property.
So finally a questions: Why there is no "URxvt" string in the output of the script?
-
Shi B. over 4 yearsThank you for the excellent answer Martin. However, would you consider revise your code? Because you are iterating the children of the root window and for each of the child, you are printing the parent WM_CLASS instead of the child's WM_CLASS. Changiing line 6 into print(indent, w.get_wm_class()) would make it much more meaningful in this case.
-
Martin Jiřička over 4 years@ShiB. Thank you for spotting the mistake! I fixed it exactly as you said.