使用 Python 的 Xlib 查找某个 X 窗口

Mar*_*čka 10 python x11

我试图在我的 X 服务器上找到一个未映射的窗口,以便将它映射回来并向它发送一些EWMH提示。因为窗口未映射,所以我不能使用 EWMH 直接询问窗口管理器。所以我试图通过 Xlib 获得它,但我遇到了它的问题。整个 API 对我来说非常混乱。

我正在使用 Python 的Xlib 包装器。现在让我们看看以下 Python 脚本:

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())
Run Code Online (Sandbox Code Playgroud)

脚本的输出是什么?一个打开的 URXVT 终端是这样的:

None
None
None
None
('xscreensaver', 'XScreenSaver')
('firefox', 'Firefox')
('Toplevel', 'Firefox')
None
('Popup', 'Firefox')
None
('Popup', 'Firefox')
('VIM', 'Vim_xterm')
Run Code Online (Sandbox Code Playgroud)

但是当我运行这个命令并点击打开的终端时:

$ xprop | grep WM_CLASS
WM_CLASS(STRING) = "urxvt", "URxvt"
Run Code Online (Sandbox Code Playgroud)

WM_NAME属性也是如此

所以最后一个问题:为什么脚本输出中没有“URxvt”字符串?

Mar*_*čka 7

没有字符串"urxvt", "URxvt" 的原因是 XWindows 在层次结构中。出于某种原因,在我的桌面上,urxvt 窗口不在第一级。

所以必须像这样遍历整棵树:

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, '-')
Run Code Online (Sandbox Code Playgroud)

一行(可能很长)脚本输出是:

--- ('urxvt', 'URxvt')
Run Code Online (Sandbox Code Playgroud)

  • @ShiB。感谢您发现错误!我完全按照你说的修好了。 (2认同)