From ce71c3f67baccd3e980975f090e89cf13a5bfa97 Mon Sep 17 00:00:00 2001 From: Sébastien Dailly Date: Sun, 4 May 2025 10:56:31 +0200 Subject: Handle invisible exception in the xlib code --- xlib.py | 110 +++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 60 insertions(+), 50 deletions(-) (limited to 'xlib.py') diff --git a/xlib.py b/xlib.py index 159e1c8..09ec18f 100644 --- a/xlib.py +++ b/xlib.py @@ -25,65 +25,75 @@ class Listener(Thread): 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 + self.disp = Xlib.display.Display() + root = self.disp.screen().root root.change_attributes(event_mask=Xlib.X.PropertyChangeMask) + self.NET_WM_NAME = self.disp.intern_atom('_NET_WM_NAME') + self.WM_CLASS = self.disp.intern_atom('WM_CLASS') + self.NET_ACTIVE_WINDOW = self.disp.intern_atom('_NET_ACTIVE_WINDOW') component.handle(Debug("Waiting for xlib event")) self.running = True while self.running: - event = disp.next_event() + 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_prop = window.get_full_property(NET_WM_NAME, 0) - if window_prop is None: - continue - window_name = str(window_prop.value).lower() - class_name = str(window.get_full_property(WM_CLASS, 0).value).lower() - except Xlib.error.XError: - continue + self.handle_event(root, self.disp.next_event()) + except Exception as e: + component.handle(Debug( str(e) )) + print(e) + + def handle_event(self, root, event): + try: + window_id_property = root.get_full_property(self.NET_ACTIVE_WINDOW, Xlib.X.AnyPropertyType) + if window_id_property is None: + return + window_id = window_id_property.value[0] + window = self.disp.create_resource_object('window', window_id) + window_prop = window.get_full_property(self.NET_WM_NAME, 0) + if window_prop is None: + return + window_name = str(window_prop.value).lower() + class_name = str(window.get_full_property(self.WM_CLASS, 0).value).lower() + except Xlib.error.XError: + return + + if window_name is None or window_name == self.active_window: + return - if window_name is None or window_name == self.active_window: + self.active_window = window_name + found = False + + # Create a reveverse dictionnary for getting the users added first + # In python, the elements in a dictionnary are sorted by insertion + # order, so we get the user added first here + for pattern in reversed(self.mapping): + # Ignore the default layout + if pattern == "default": + continue + if not (pattern.lstrip() in window_name or pattern.lstrip() in class_name): continue + code = self.mapping[pattern] + # We found something. At this point, even if we do not update + # the layer (because it is the same as the previous) we do not + # switch back to the default layer. + found = True + if code != self.last_code: + + component.handle(Debug("Switching to '%s' for '%s'" % (pattern, window_name))) + self.queue.put ( (code, None) ) + self.last_code = code + # We found a matching configuration. Even if the match is the + # same as the current one, we break the loop in order to + # prevent another layer to update. + break + if not found and self.last_code != "default": + default = self.mapping.get("default", None) + if default is None: + return + + self.queue.put ( (default, None) ) + self.last_code = "default" - self.active_window = window_name - found = False - - # Create a reveverse dictionnary for getting the users added first - # In python, the elements in a dictionnary are sorted by insertion - # order, so we get the user added first here - for pattern in reversed(self.mapping): - # Ignore the default layout - if pattern == "default": - continue - if not (pattern.lstrip() in window_name or pattern.lstrip() in class_name): - continue - code = self.mapping[pattern] - # We found something. At this point, even if we do not update - # the layer (because it is the same as the previous) we do not - # switch back to the default layer. - found = True - if code != self.last_code: - - component.handle(Debug("Switching to '%s' for '%s'" % (pattern, window_name))) - self.queue.put ( (code, None) ) - self.last_code = code - # We found a matching configuration. Even if the match is the - # same as the current one, we break the loop in order to - # prevent another layer to update. - break - if not found and self.last_code != "default": - default = self.mapping.get("default", None) - if default is None: - continue - - self.queue.put ( (default, None) ) - self.last_code = "default" def stop(self): self.running = False -- cgit v1.2.3