aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xlib.py43
1 files changed, 32 insertions, 11 deletions
diff --git a/xlib.py b/xlib.py
index b4954da..ba8f02b 100644
--- a/xlib.py
+++ b/xlib.py
@@ -1,5 +1,6 @@
from threading import Thread
+from contextlib import contextmanager
import Xlib
import Xlib.display
@@ -11,13 +12,27 @@ from interfaces.message import Debug
from interfaces import desktopEvent
from consumer import Mapping
+
+@contextmanager
+def window_obj(disp, win_id):
+ """Simplify dealing with BadWindow (make it either valid or None)"""
+ window_obj = None
+ if win_id:
+ try:
+ window_obj = disp.create_resource_object('window', win_id)
+ except Xlib.error.XError:
+ pass
+ yield window_obj
+
+
@interface.implementer(desktopEvent.IDesktop)
class Listener(Thread):
def __init__(self, mapping):
super().__init__()
self.mapping = mapping
- self.active_window = None
+ self.active_name = None
+ self.active_window_id = None
self.last_code = None
self.running = False
self.daemon = True
@@ -25,7 +40,7 @@ class Listener(Thread):
def getForegroundWindowTitle(self):
""" Return the name of the selected window
"""
- return self.active_window
+ return self.active_name
def run(self):
self.disp = Xlib.display.Display()
@@ -43,7 +58,7 @@ class Listener(Thread):
try:
self.handle_event(root, self.disp.next_event())
except Exception as e:
- component.handle(Debug( str(e) ))
+ component.handle(Debug(str(e)))
print(e)
def get_property_value(self, window, property_):
@@ -54,7 +69,6 @@ class Listener(Thread):
return str(prop_name.value).lower()
return None
-
def handle_event(self, root, _event):
try:
window_id_property = root.get_full_property(
@@ -64,18 +78,25 @@ class Listener(Thread):
if window_id_property is None:
return
window_id = window_id_property.value[0]
- window = self.disp.create_resource_object('window', window_id)
-
- window_name = self.get_property_value(window, self.NET_WM_NAME) \
- or self.get_property_value(window, self.WM_NAME)
- class_name = self.get_property_value(window, self.WM_CLASS)
+ if self.active_window_id is not None and window_id != self.active_window_id:
+ with window_obj(self.disp, self.active_window_id) as window:
+ if window is not None:
+ window.change_attributes(event_mask=Xlib.X.NoEventMask)
+ with window_obj(self.disp, window_id) as window:
+ window.change_attributes(event_mask=Xlib.X.PropertyChangeMask)
+ self.active_window_id = window_id
+
+ with window_obj(self.disp, self.active_window_id) as window:
+ window_name = self.get_property_value(window, self.NET_WM_NAME) \
+ or self.get_property_value(window, self.WM_NAME)
+ class_name = self.get_property_value(window, self.WM_CLASS)
except Xlib.error.XError:
return
- if window_name is None or window_name == self.active_window:
+ if window_name is None or window_name == self.active_name:
return
- self.active_window = window_name
+ self.active_name = window_name
found = False
# Create a reveverse dictionnary for getting the users added first