Browse Source

throw action: release key after 40-80ms

Fabian Peter Hammerle 4 years ago
parent
commit
f81dc33c13
3 changed files with 73 additions and 34 deletions
  1. 2 2
      README.md
  2. 3 2
      rescriptoon/__init__.py
  3. 68 30
      rescriptoon/_actions.py

+ 2 - 2
README.md

@@ -43,13 +43,13 @@ $ rescriptoon --toggle slash
 | s     | walk backward                   | 0             |
 | a     | turn left                       | 0             |
 | d     | turn right                      | 0             |
-| v     | throw pie                       | 0             |
+| v     | low throw                       | 0             |
 | i     | walk forward                    | 1             |
 | k     | walk backward                   | 1             |
 | j     | turn left                       | 1             |
 | l     | turn right                      | 1             |
 | /     | jump                            | 1             |
-| n     | throw pie                       | 1             |
+| n     | low throw                       | 1             |
 | space | jump                            | all           |
 
 ### Gag Selection

+ 3 - 2
rescriptoon/__init__.py

@@ -9,6 +9,7 @@ import Xlib.display
 from Xlib import XK, X, Xatom
 
 from rescriptoon._actions import (
+    LowThrowAction,
     RewriteKeyEventAction,
     SelectGagAction,
     ToggleOverlayAction,
@@ -26,13 +27,13 @@ EXTENDED_CONTROLS_DEFAULT_KEYSYM_MAPPINGS = {
     XK.XK_Control_L: RewriteKeyEventAction(
         keysym=XK.XK_Control_L, target_engine_index=0
     ),
-    XK.XK_v: RewriteKeyEventAction(keysym=XK.XK_Delete, target_engine_index=0),
+    XK.XK_v: LowThrowAction(target_engine_index=0),
     XK.XK_i: RewriteKeyEventAction(keysym=XK.XK_Up, target_engine_index=1),
     XK.XK_j: RewriteKeyEventAction(keysym=XK.XK_Left, target_engine_index=1),
     XK.XK_k: RewriteKeyEventAction(keysym=XK.XK_Down, target_engine_index=1),
     XK.XK_l: RewriteKeyEventAction(keysym=XK.XK_Right, target_engine_index=1),
     XK.XK_slash: RewriteKeyEventAction(keysym=XK.XK_Control_L, target_engine_index=1),
-    XK.XK_n: RewriteKeyEventAction(keysym=XK.XK_Delete, target_engine_index=1),
+    XK.XK_n: LowThrowAction(target_engine_index=1),
     XK.XK_space: RewriteKeyEventAction(keysym=XK.XK_Control_L),
     XK.XK_e: SelectGagAction(
         target_engine_index=0, column_index=4, factor_y=-0.047

+ 68 - 30
rescriptoon/_actions.py

@@ -1,9 +1,16 @@
 import abc
 import logging
+import random
+import time
 import typing
 
 import Xlib.protocol.event
 import Xlib.X
+import Xlib.XK
+
+_XKEYEVENT_TYPE = typing.Union[
+    Xlib.protocol.event.KeyPress, Xlib.protocol.event.KeyRelease
+]
 
 
 class EngineAction:
@@ -14,19 +21,13 @@ class EngineAction:
     def execute_on_window(
         self,
         overlay: "rescriptoon.Overlay",
-        xkeyevent: typing.Union[
-            Xlib.protocol.event.KeyPress, Xlib.protocol.event.KeyRelease
-        ],
+        xkeyevent: _XKEYEVENT_TYPE,
         engine_window: "Xlib.display.Window",
     ):
         raise NotImplementedError()
 
     def execute(
-        self,
-        overlay: "rescriptoon.Overlay",
-        xkeyevent: typing.Union[
-            Xlib.protocol.event.KeyPress, Xlib.protocol.event.KeyRelease
-        ],
+        self, overlay: "rescriptoon.Overlay", xkeyevent: _XKEYEVENT_TYPE,
     ):
         if self._target_engine_index is None:
             for target_window in overlay.engine_windows:
@@ -49,9 +50,7 @@ class CenterClickAction(EngineAction):
     def execute_on_window(
         self,
         overlay: "rescriptoon.Overlay",
-        xkeyevent: typing.Union[
-            Xlib.protocol.event.KeyPress, Xlib.protocol.event.KeyRelease
-        ],
+        xkeyevent: _XKEYEVENT_TYPE,
         engine_window: "Xlib.display.Window",
     ):
         engine_geometry = engine_window.get_geometry()
@@ -93,6 +92,31 @@ class SelectGagAction(CenterClickAction):
         )
 
 
+def _send_rewritten_xkeyevent(
+    event_template: _XKEYEVENT_TYPE,
+    window: "Xlib.display.Window",
+    event_type: typing.Optional[typing.Type] = None,
+    keycode=None,
+) -> _XKEYEVENT_TYPE:
+    if not event_type:
+        event_type = type(event_template)
+    window.send_event(
+        event_type(
+            window=window,
+            detail=keycode if keycode else event_template.detail,
+            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,
+        )
+    )
+
+
 class RewriteKeyEventAction(EngineAction):
     def __init__(self, target_engine_index: typing.Optional[int] = None, keysym=None):
         super().__init__(target_engine_index=target_engine_index,)
@@ -101,27 +125,41 @@ class RewriteKeyEventAction(EngineAction):
     def execute_on_window(
         self,
         overlay: "rescriptoon.Overlay",
-        xkeyevent: typing.Union[
-            Xlib.protocol.event.KeyPress, Xlib.protocol.event.KeyRelease
-        ],
+        xkeyevent: _XKEYEVENT_TYPE,
         engine_window: "Xlib.display.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,
-            )
+        _send_rewritten_xkeyevent(
+            event_template=xkeyevent,
+            window=engine_window,
+            keycode=overlay.xdisplay.keysym_to_keycode(self._keysym),
+        )
+
+
+class LowThrowAction(EngineAction):
+
+    _THROW_KEYSYM = Xlib.XK.XK_Delete  # pylint: no-member
+
+    def execute_on_window(
+        self,
+        overlay: "rescriptoon.Overlay",
+        xkeyevent: _XKEYEVENT_TYPE,
+        engine_window: "Xlib.display.Window",
+    ):
+        if isinstance(xkeyevent, Xlib.protocol.event.KeyRelease):
+            return
+        keycode = overlay.xdisplay.keysym_to_keycode(self._THROW_KEYSYM)
+        _send_rewritten_xkeyevent(
+            event_template=xkeyevent,
+            window=engine_window,
+            keycode=keycode,
+            event_type=Xlib.protocol.event.KeyPress,
+        )
+        time.sleep(random.uniform(0.04, 0.08))
+        _send_rewritten_xkeyevent(
+            event_template=xkeyevent,
+            window=engine_window,
+            keycode=keycode,
+            event_type=Xlib.protocol.event.KeyRelease,
         )