diff options
Diffstat (limited to 'main.py')
| -rw-r--r-- | main.py | 123 |
1 files changed, 54 insertions, 69 deletions
@@ -1,76 +1,61 @@ +import Xlib from Xlib.display import Display -from Xlib import X -from Xlib.ext import record -from Xlib.protocol import rq +from Xlib import X, XK +from Xlib.ext import xtest +from Xlib.protocol import event +from normal import normal_mode import time -from constants import KEYSYM_MAP, NORMAL -from mode import mode -from normal import normal_mode +MASK = X.Mod2Mask -class ShortcutManager(): +class Manager(): def __init__(self): - self.disp2 = Display() - - def is_inkscape(self): - window = self.disp2.get_input_focus().focus - cls = window.get_wm_class() - return cls and cls[0] == 'inkscape' - - def meta_handler(self, handler): - def handle(reply): - print('yes') - data = reply.data - while len(data): - event, data = rq.EventField(None).parse_binary_value( - data, self.disp.display, None, None) - - if not self.is_inkscape(): - return - - keysym = self.disp.keycode_to_keysym(event.detail, 0) - handler(event, keysym, self) - - return handle - - def listen(self, handler): self.disp = Display() - root = self.disp.screen().root - self.ctx = self.disp.record_create_context( - # datum_flags - 0, - # clients - [record.AllClients], - # rangers - [{ - 'core_requests': (0, 0), - 'core_replies': (0, 0), - 'ext_requests': (0, 0, 0, 0), - 'ext_replies': (0, 0, 0, 0), - 'delivered_events': (0, 0), - 'device_events': (0x02, 0x05), - 'errors': (0, 0), - 'client_started': False, - 'client_died': False, - }]) - - self.disp.record_enable_context(self.ctx, self.meta_handler(handler)) - self.disp.record_free_context(self.ctx) - - try: - while True: - time.sleep(1) - # Infinite wait, doesn't do anything as no events are grabbed - event = root.display.next_event() - except: - print('exception!') - - def teardown(self): - self.disp.record_disable_context(self.ctx) - -sm = ShortcutManager() -mode('INIT') -time.sleep(1) -mode(NORMAL) -sm.listen(normal_mode) + self.screen = self.disp.screen() + self.root = self.screen.root + self.inkscape = next( + w for w in self.root.query_tree().children + if w.get_wm_class() and w.get_wm_class()[0] == 'inkscape' + ) + self.mode = normal_mode + + def event(self, name, detail, state): + return name( + time = X.CurrentTime, + root = self.root, + window = self.inkscape, + same_screen = 0, child = Xlib.X.NONE, + root_x = 0, root_y = 0, event_x = 0, event_y = 0, + state = state, + detail = detail + ) + + def press(self, key, mask=X.NONE): + keysym = XK.string_to_keysym(key) + keycode = self.disp.keysym_to_keycode(keysym) + self.inkscape.send_event(self.event(event.KeyPress, keycode, mask), propagate = True) + self.inkscape.send_event(self.event(event.KeyRelease, keycode, mask), propagate = True) + self.disp.flush() + self.disp.sync() + + def grab(self): + self.inkscape.grab_key(X.AnyKey, X.AnyModifier, True, X.GrabModeAsync, X.GrabModeAsync) + self.inkscape.change_attributes(event_mask = X.KeyReleaseMask | X.KeyPressMask) + + def ungrab(self): + self.inkscape.ungrab_key(X.AnyKey, X.AnyModifier, True, X.GrabModeAsync, X.GrabModeAsync) + + def listen(self): + self.grab() + while True: + evt = self.disp.next_event() + if evt.type in [X.KeyPress, X.KeyRelease]: #ignore X.MappingNotify(=34) + keycode = evt.detail + keysym = self.disp.keycode_to_keysym(keycode, 0) + char = XK.keysym_to_string(keysym) + self.disp.allow_events(X.ReplayKeyboard, X.CurrentTime) + self.mode(self, evt, char) + +m = Manager() +m.listen() |
