123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- import abc
- import logging
- import typing
- import Xlib.protocol.event
- import Xlib.X
- class EngineAction:
- def __init__(self, target_engine_index: typing.Optional[int] = None):
- self._target_engine_index = target_engine_index
- @abc.abstractmethod
- def execute_on_window(self, overlay, xkeyevent, engine_window):
- raise NotImplementedError()
- def execute(self, overlay, xkeyevent):
- if not self._target_engine_index:
- for target_window in overlay.engine_windows:
- self.execute_on_window(overlay, xkeyevent, target_window)
- elif self._target_engine_index >= len(overlay.engine_windows):
- logging.warning("target engine index out of bounds")
- else:
- self.execute_on_window(
- overlay, xkeyevent, overlay.engine_windows[self._target_engine_index]
- )
- class CenterClickAction(EngineAction):
- def __init__(self, target_engine_index, factor_x, factor_y):
- super().__init__(target_engine_index=target_engine_index,)
- self._button = Xlib.X.Button1
- self._factor_x = factor_x
- self._factor_y = factor_y
- def execute_on_window(self, overlay, xkeyevent, engine_window):
- engine_geometry = engine_window.get_geometry()
- smaller_dimension = min(engine_geometry.width, engine_geometry.height)
- attr = dict(
- window=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)
- engine_window.send_event(e)
- class SelectGagAction(CenterClickAction):
- X_OFFSET = -0.286
- X_FACTOR = 0.081
- def __init__(self, target_engine_index, column_index, factor_y):
- super().__init__(
- target_engine_index=target_engine_index,
- factor_x=self.X_OFFSET + self.X_FACTOR * column_index,
- factor_y=factor_y,
- )
- class RewriteKeyEventAction(EngineAction):
- def __init__(self, target_engine_index: typing.Optional[int] = None, keysym=None):
- super().__init__(target_engine_index=target_engine_index,)
- self._keysym = keysym
- def execute_on_window(self, overlay, xkeyevent, engine_window):
- engine_window.send_event(
- type(xkeyevent)(
- window=engine_window,
- detail=overlay.xdisplay.keysym_to_keycode(self._keysym)
- if self._keysym
- else xkeyevent.detail,
- state=xkeyevent.state,
- root_x=xkeyevent.root_x,
- root_y=xkeyevent.root_y,
- event_x=xkeyevent.event_x,
- event_y=xkeyevent.event_y,
- child=xkeyevent.child,
- root=xkeyevent.root,
- time=xkeyevent.time, # X.CurrentTime
- same_screen=xkeyevent.same_screen,
- )
- )
- class ToggleOverlayAction:
- def execute(self, overlay, xkeyevent):
- if isinstance(xkeyevent, Xlib.protocol.event.KeyPress):
- overlay.toggle()
|