Xlib有活动窗口事件吗?

5

我正在尝试使用Xlib编写一个程序,用于跟踪活动窗口何时发生变化。但是我还不确定最佳的实现方式,以下是我的想法:

  • 每秒钟使用_NET_ACTIVE_WINDOW获取活动窗口,如果有变化则运行相关事件的代码。
  • 获取所有窗口的列表,并监听它们的焦点事件。但我需要找出如何保持最新的打开窗口列表。

是否有更简单/更好的方法?我对使用Xlib进行编程还比较新手。


监听所有焦点事件并为所有窗口注册所有处理程序似乎非常昂贵。我想知道,实际上,是否一般听取PointerMove,然后从事件处理程序调用XGetInputFocus()来查找移动时谁拥有它会减少开销。这必须多实时?如果答案是“一秒钟可以”,那么轮询方法似乎是最好的。 - FrankH.
不必实时,几秒钟内就可以。我会尝试我的第一种方法。谢谢FrankH。 - Jim
3个回答

7

这是@alanc提出的Python实现。

import Xlib
import Xlib.display

disp = Xlib.display.Display()
root = disp.screen().root

NET_ACTIVE_WINDOW = disp.intern_atom('_NET_ACTIVE_WINDOW')
NET_WM_NAME = disp.intern_atom('_NET_WM_NAME')

last_seen = {'xid': None}
def get_active_window():
    window_id = root.get_full_property(NET_ACTIVE_WINDOW,
                                       Xlib.X.AnyPropertyType).value[0]

    focus_changed = (window_id != last_seen['xid'])
    last_seen['xid'] = window_id

    return window_id, focus_changed

def get_window_name(window_id):
    try:
        window_obj = disp.create_resource_object('window', window_id)
        window_name = window_obj.get_full_property(NET_WM_NAME, 0).value
    except Xlib.error.XError:
        window_name = None

    return window_name


if __name__ == '__main__':
    root.change_attributes(event_mask=Xlib.X.PropertyChangeMask)
    while True:
        win, changed = get_active_window()
        if changed:
            print(get_window_name(win))

        while True:
            event = disp.next_event()
            if (event.type == Xlib.X.PropertyNotify and
                    event.atom == NET_ACTIVE_WINDOW):
                break

我为某人编写的更加详细注释的示例版本在这个代码片段中。


3

您是否可以在根窗口上选择PropertyChange,以便在更新任何属性时发送PropertyNotify事件,然后检查每个事件以查看它是否是_NET_ACTIVE_WINDOW的事件?


0
我也一直在寻找“活动窗口变化事件抓取器”。目前我使用的方法是结合xdotoolxwininfo,这也许对你有所帮助。
xwininfo -id "$(xdotool getactivewindow)"

这会获取活动窗口信息,但它如何帮助注册事件处理程序呢? - phil294

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接