Tìm cửa sổ X nhất định với Xlib của Python


8

Tôi đang cố gắng tìm một cửa sổ chưa được ánh xạ trên máy chủ X của mình để ánh xạ lại và gửi cho nó một số gợi ý EWMH . Vì cửa sổ không được ánh xạ nên tôi không thể sử dụng EWMH để hỏi người quản lý cửa sổ trực tiếp. Vì vậy, tôi đang cố gắng để có được nó thông qua Xlib, nhưng tôi đang gặp vấn đề với nó. Toàn bộ API rất khó hiểu đối với tôi.

Tôi đang sử dụng trình bao bọc Xlib của Python . Bây giờ hãy xem đoạn mã Python sau:

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())

Đầu ra của kịch bản là gì? Một thiết bị đầu cuối URXVT đã mở và một cái gì đó như thế này:

None
None
None
None
('xscreensaver', 'XScreenSaver')
('firefox', 'Firefox')
('Toplevel', 'Firefox')
None
('Popup', 'Firefox')
None
('Popup', 'Firefox')
('VIM', 'Vim_xterm')

Nhưng khi tôi chạy lệnh này và bấm vào thiết bị đầu cuối đã mở:

$ xprop | grep WM_CLASS
WM_CLASS(STRING) = "urxvt", "URxvt"

Điều tương tự là với tài sản WM_NAME .

Vì vậy, cuối cùng một câu hỏi: Tại sao không có chuỗi "URxvt" trong đầu ra của tập lệnh?

Câu trả lời:


5

Lý do tại sao không có chuỗi "urxvt", "URxvt" là vì XWindows đang ở chế độ chữ tượng hình. Và vì một số lý do, trên máy tính để bàn của tôi, các cửa sổ urxvt không ở cấp độ đầu tiên.

Vì vậy, người ta phải đi qua toàn bộ cây như thế này:

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, '-')

Sau đó, một dòng của đầu ra tập lệnh (có thể khá dài) là:

--- ('urxvt', 'URxvt')

1
Cảm ơn bạn đã trả lời tuyệt vời Martin. Tuy nhiên, bạn sẽ xem xét sửa đổi mã của bạn? Bởi vì bạn đang lặp lại các con của cửa sổ gốc và đối với mỗi đứa trẻ, bạn đang in WM_CLASS của cha mẹ thay vì WM_CLASS của con. Thay đổi dòng 6 thành bản in (thụt lề, w.get_wm_group ()) sẽ làm cho nó có ý nghĩa hơn nhiều trong trường hợp này.
Shi B.

2
@ShiB. Cảm ơn bạn đã phát hiện ra sai lầm! Tôi đã sửa nó chính xác như bạn nói.
Martin Jiřička
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.