开发者

Capture change in active window (for linux)

Is there a way to know when a (linux x windows) user changes the active window through alt-tab or click. I want to write a script that listens for this event (if such an event occurs, the script then goes on to find the current active window - which I know how to solve). I could also keep polling to find the current active window but that's a bad way to write this. Hoping to get a solution tha开发者_JS百科t can "listen" rather than "poll".

Thanks!


I had a need to do that and my solution was to watch the _NET_ACTIVE_WINDOW property (maintained by the Window Manager) on the root window for changes.

Here's a copy of the python-xlib implementation I wrote to demonstrate it to someone:

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

The more fully-commented version is in this gist.


Just briefly looking through the documentation for the Perl module X11::Tops indicates that there is a monitor_property_and_structure_change method. I would thus guess that the underlying X11 libraries will provide the functionality you are looking for.


I know about KTimeTracker KDE program which tracks how much time you've spend in each window. I don't know about details - whether it tracks events of changing active windows, or just periodically checks status of whole desktop. Nevertheless, sources might be helpful : http://www.kde.org/applications/utilities/ktimetracker/ .

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜