From 02d676bda89c2fb8469ea81f7429c19c1e29df7c Mon Sep 17 00:00:00 2001 From: Sébastien Dailly Date: Sat, 15 Jul 2023 14:44:41 +0200 Subject: Initial commit --- xlib.py | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 xlib.py (limited to 'xlib.py') diff --git a/xlib.py b/xlib.py new file mode 100644 index 0000000..b86a8b1 --- /dev/null +++ b/xlib.py @@ -0,0 +1,62 @@ +#!/usr/bin/python3 +import Xlib +import Xlib.display + +from zope import interface +from interfaces import desktopEvent +from threading import Thread + +from interfaces.message import IMessage, Debug +from zope import component + +@interface.implementer(desktopEvent.IDesktop) +class Listener(Thread): + + def __init__(self, mapping, queue): + Thread.__init__(self) + self.queue = queue + self.mapping = mapping + self.active_window = None + self.last_code = None + self.running = False + + def getForegroundWindowTitle(self): + """ Return the name of the selected window + """ + return self.active_window + + def run(self): + disp = Xlib.display.Display() + NET_WM_NAME = disp.intern_atom('_NET_WM_NAME') + WM_CLASS = disp.intern_atom('WM_CLASS') + NET_ACTIVE_WINDOW = disp.intern_atom('_NET_ACTIVE_WINDOW') + root = disp.screen().root + root.change_attributes(event_mask=Xlib.X.PropertyChangeMask) + + component.handle(Debug("Waiting for xlib event")) + self.running = True + while self.running: + try: + window_id = root.get_full_property(NET_ACTIVE_WINDOW, Xlib.X.AnyPropertyType).value[0] + window = disp.create_resource_object('window', window_id) + window.change_attributes(event_mask=Xlib.X.PropertyChangeMask) + window_name = str(window.get_full_property(NET_WM_NAME, 0).value).lower() + class_name = str(window.get_full_property(WM_CLASS, 0).value).lower() + except Xlib.error.XError: + window_name = None + class_name = None + + if window_name is not None and window_name != self.active_window: + + self.active_window = window_name + for pattern, code in self.mapping.items(): + if (pattern in window_name or pattern in class_name) and code != self.last_code: + + component.handle(Debug("Switching to '%s' for '%s'" % (code, window_name))) + self.queue.put ( (code, None) ) + self.last_code = code + break + event = disp.next_event() + + def stop(self): + self.running = False -- cgit v1.2.3