Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/grails/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Python xlib在活动X窗口更改时获取通知_Python_X11_Xlib - Fatal编程技术网

使用Python xlib在活动X窗口更改时获取通知

使用Python xlib在活动X窗口更改时获取通知,python,x11,xlib,Python,X11,Xlib,我想监控在运行X的Linux系统上哪个窗口是活动的,以及该活动窗口何时被调整大小或移动。我可以监视活动窗口(它保存在根窗口上的\u NET\u active\u window属性中,我可以注册根窗口上的属性通知事件以发现该属性何时更改)。但是,我不知道如何监视活动窗口,以了解它是否被调整大小或移动 import Xlib import Xlib.display disp = Xlib.display.Display() Xroot = disp.screen().root NET_ACTIVE

我想监控在运行X的Linux系统上哪个窗口是活动的,以及该活动窗口何时被调整大小或移动。我可以监视活动窗口(它保存在根窗口上的
\u NET\u active\u window
属性中,我可以注册根窗口上的
属性通知
事件以发现该属性何时更改)。但是,我不知道如何监视活动窗口,以了解它是否被调整大小或移动

import Xlib
import Xlib.display

disp = Xlib.display.Display()
Xroot = disp.screen().root
NET_ACTIVE_WINDOW = disp.intern_atom('_NET_ACTIVE_WINDOW')
Xroot.change_attributes(event_mask=Xlib.X.PropertyChangeMask)

while True:
    # loop until an event happens that we care about
    # we care about a change to which window is active
    # (NET_ACTIVE_WINDOW property changes on the root)
    # or about the currently active window changing
    # in size or position (don't know how to do this)
    event = disp.next_event()
    if (event.type == Xlib.X.PropertyNotify and
            event.atom == NET_ACTIVE_WINDOW):
        active = disp.get_input_focus().focus
        try:
            name = active.get_wm_class()[1]
        except TypeError:
            name = "unknown"
        print("The active window has changed! It is now", name)
有办法做到这一点吗?它可能涉及侦听当前活动窗口上的ConfigureNotify事件(并在该窗口变为活动状态时调用该窗口上的
change\u attributes
,以设置适当的掩码),但我无法使其正常工作

(注意:我没有使用Gtk,所以请不要使用Gtk解决方案。)


更新:通过观察活动窗口中
\u NET\u WM\u OPAQUE\u REGION
属性更改的值(因为我正确地接收到PropertyChange事件,尽管我没有接收到ConfigureNotify事件),有一种相当可疑的方法来检测窗口的大小调整。然而,不清楚是否所有的窗口管理器都设置了这个属性,这只会改变窗口的大小;它不会在窗口移动时更改(也不会更改任何其他属性)。

执行此操作的方法是在根窗口上为
子结构NotifyMask
选择,然后读取所有
ConfigureNotify
事件并忽略我们关心的窗口以外的事件,因此:

import Xlib
import Xlib.display

disp = Xlib.display.Display()
Xroot = disp.screen().root
NET_ACTIVE_WINDOW = disp.intern_atom('_NET_ACTIVE_WINDOW')
Xroot.change_attributes(event_mask=Xlib.X.PropertyChangeMask |
                        Xlib.X.SubstructureNotifyMask)

windows = []

while True:
    # loop until an event happens that we care about
    # we care about a change to which window is active
    # (NET_ACTIVE_WINDOW property changes on the root)
    # or about the currently active window changing
    # in size or position (ConfigureNotify event for
    # our window or one of its ancestors)
    event = disp.next_event()
    if (event.type == Xlib.X.PropertyNotify and
            event.atom == NET_ACTIVE_WINDOW):
        active = disp.get_input_focus().focus
        try:
            name = active.get_wm_class()[1]
        except TypeError:
            name = "unknown"
        print("The active window has changed! It is now", name)

        # Because an X window is not necessarily just what one thinks of
        # as a window (the window manager may add an invisible frame, and
        # so on), we record not just the active window but its ancestors
        # up to the root, and treat a ConfigureNotify on any of those
        # ancestors as meaning that the active window has been moved or resized
        pointer = active
        windows = []
        while pointer.id != Xroot.id:
            windows.append(pointer)
            pointer = pointer.query_tree().parent
    elif event.type == Xlib.X.ConfigureNotify and event.window in windows:
        print("Active window size/position is now", event.x, event.y,
              event.width, event.height)