try: import Xlib.X import Xlib.protocol.event except ImportError: pass class SelectGagAction: def __init__(self, factor_x, factor_y): self._button = Xlib.X.Button1 self._factor_x = factor_x self._factor_y = factor_y def execute(self, extended_controls, xkeyevent): engine_geometry = extended_controls._engine_window.get_geometry() smaller_dimension = min(engine_geometry.width, engine_geometry.height) attr = dict( window=extended_controls.engine_window, detail=self._button, state=xkeyevent.state, event_x=int(engine_geometry.width / 2 + smaller_dimension * self._factor_x), event_y=int(engine_geometry.height / 2 + smaller_dimension * self._factor_y), # apparently root_x & root_y do not need to correspond with event_x/y. # attributes are still required to be set. root_x=0, # xkeyevent.root_x, root_y=0, # xkeyevent.root_y, child=xkeyevent.child, root=xkeyevent.root, time=xkeyevent.time, # X.CurrentTime same_screen=xkeyevent.same_screen, ) if isinstance(xkeyevent, Xlib.protocol.event.KeyPress): e = Xlib.protocol.event.ButtonPress(**attr) else: e = Xlib.protocol.event.ButtonRelease(**attr) extended_controls.engine_window.send_event(e) class TargetEngine: Primary = 1 << 0 NonPrimary = 1 << 1 All = Primary | NonPrimary class RewriteKeyEventAction: def __init__(self, keysym=None, target_engine=TargetEngine.Primary): self._keysym = keysym self._target_engine = target_engine @staticmethod def _send_event(event_template, keycode, target_window): target_window.send_event(type(event_template)( window=target_window, detail=keycode, state=event_template.state, root_x=event_template.root_x, root_y=event_template.root_y, event_x=event_template.event_x, event_y=event_template.event_y, child=event_template.child, root=event_template.root, time=event_template.time, # X.CurrentTime same_screen=event_template.same_screen, )) def execute(self, extended_controls, xkeyevent): defaults = dict( keycode=extended_controls.xdisplay.keysym_to_keycode(self._keysym) if self._keysym else xkeyevent.detail, event_template=xkeyevent, ) if self._target_engine & TargetEngine.Primary: self._send_event( target_window=extended_controls.engine_window, **defaults, ) if self._target_engine & TargetEngine.NonPrimary: for win in extended_controls.other_engine_windows: self._send_event(target_window=win, **defaults) class ForwardKeyEventAction(RewriteKeyEventAction): def __init__(self): super().__init__(keysym=None) class ToggleExtendedControlsAction: def execute(self, extended_controls, xkeyevent): if isinstance(xkeyevent, Xlib.protocol.event.KeyPress): extended_controls.toggle()