diff options
| -rw-r--r-- | xlib.py | 110 | 
1 files changed, 60 insertions, 50 deletions
| @@ -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
 | 
