Просмотр исходного кода

extended controls: assign target indices to running engines;
RewriteKeyEventAction now targets engines by target index

Fabian Peter Hammerle 6 лет назад
Родитель
Сommit
5021fd73da
3 измененных файлов с 93 добавлено и 93 удалено
  1. 12 12
      README.md
  2. 50 39
      tooncher/actions.py
  3. 31 42
      tooncher/controls.py

+ 12 - 12
README.md

@@ -74,20 +74,20 @@ $ tooncher --cpu-limit 70 cfo
 
 ## Extended Controls Default Mappings
 
-| Key   | Action                          | Target Window |
+| Key   | Action                          | Target Engine |
 | ----- | ------------------------------- | ------------- |
 | `     | turn Extended Controls on / off |               |
-| w     | walk forward                    | primary       |
-| s     | walk backward                   | primary       |
-| a     | turn left                       | primary       |
-| d     | turn right                      | primary       |
-| v     | throw pie                       | primary       |
-| i     | walk forward                    | non-primary   |
-| k     | walk backward                   | non-primary   |
-| j     | turn left                       | non-primary   |
-| l     | turn right                      | non-primary   |
-| /     | jump                            | non-primary   |
-| n     | throw pie                       | non-primary   |
+| w     | walk forward                    | 0             |
+| s     | walk backward                   | 0             |
+| a     | turn left                       | 0             |
+| d     | turn right                      | 0             |
+| v     | throw pie                       | 0             |
+| i     | walk forward                    | 1             |
+| k     | walk backward                   | 1             |
+| j     | turn left                       | 1             |
+| l     | turn right                      | 1             |
+| /     | jump                            | 1             |
+| n     | throw pie                       | 1             |
 | space | jump                            | all           |
 | e     | select elephant trunk in battle | primary       |
 | f     | select fog in battle            | primary       |

+ 50 - 39
tooncher/actions.py

@@ -5,6 +5,33 @@ except ImportError:
     pass
 
 
+class TargetEngine:
+    Primary = -1
+    All = -3
+
+
+class EngineAction:
+
+    def __init__(self, target_engine_index):
+        self._target_engine_index = target_engine_index
+
+    def execute_on_window(self, extended_controls, xkeyevent, engine_window):
+        raise Exception('abstract method')
+
+    def execute(self, extended_controls, xkeyevent):
+        if self._target_engine_index == TargetEngine.Primary:
+            target_windows = [extended_controls.primary_engine_window]
+        elif self._target_engine_index == TargetEngine.All:
+            target_windows = extended_controls.engine_windows
+        else:
+            target_windows = extended_controls.engine_windows_by_target_index.get(
+                self._target_engine_index,
+                [],
+            )
+        for target_window in target_windows:
+            self.execute_on_window(extended_controls, xkeyevent, target_window)
+
+
 class SelectGagAction:
 
     def __init__(self, factor_x, factor_y):
@@ -39,54 +66,38 @@ class SelectGagAction:
         extended_controls.primary_engine_window.send_event(e)
 
 
-class TargetEngine:
-    Primary = -1
-    NonPrimary = -2
-    All = -3
+class RewriteKeyEventAction(EngineAction):
 
-
-class RewriteKeyEventAction:
-
-    def __init__(self, keysym=None, target_engine_index=TargetEngine.Primary):
+    def __init__(self, target_engine_index, keysym=None):
+        super().__init__(
+            target_engine_index=target_engine_index,
+        )
         self._keysym = keysym
-        self._target_engine_index = target_engine_index
 
-    @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)
+    def execute_on_window(self, extended_controls, xkeyevent, engine_window):
+        engine_window.send_event(type(xkeyevent)(
+            window=engine_window,
+            detail=extended_controls.xdisplay.keysym_to_keycode(self._keysym)
                 if self._keysym else xkeyevent.detail,
-            event_template=xkeyevent,
-        )
-        if self._target_engine_index in [TargetEngine.Primary, TargetEngine.All]:
-            self._send_event(
-                target_window=extended_controls.primary_engine_window,
-                **defaults,
-            )
-        if self._target_engine_index in [TargetEngine.NonPrimary, TargetEngine.All]:
-            for win in extended_controls.other_engine_windows:
-                self._send_event(target_window=win, **defaults)
+            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 ForwardKeyEventAction(RewriteKeyEventAction):
 
     def __init__(self):
-        super().__init__(keysym=None)
+        super().__init__(
+            keysym=None,
+            target_engine_index=TargetEngine.Primary,
+        )
 
 
 class ToggleExtendedControlsAction:

+ 31 - 42
tooncher/controls.py

@@ -17,39 +17,19 @@ TOONTOWN_WINDOW_NAME = 'Toontown Rewritten'
 
 if Xlib:
     EXTENDED_CONTROLS_DEFAULT_KEYSYM_MAPPINGS = {
-        XK.XK_w: RewriteKeyEventAction(keysym=XK.XK_Up),
-        XK.XK_a: RewriteKeyEventAction(keysym=XK.XK_Left),
-        XK.XK_s: RewriteKeyEventAction(keysym=XK.XK_Down),
-        XK.XK_d: RewriteKeyEventAction(keysym=XK.XK_Right),
-        XK.XK_v: RewriteKeyEventAction(keysym=XK.XK_Delete),
-        XK.XK_i: RewriteKeyEventAction(
-            keysym=XK.XK_Up,
-            target_engine_index=TargetEngine.NonPrimary,
-        ),
-        XK.XK_j: RewriteKeyEventAction(
-            keysym=XK.XK_Left,
-            target_engine_index=TargetEngine.NonPrimary,
-        ),
-        XK.XK_k: RewriteKeyEventAction(
-            keysym=XK.XK_Down,
-            target_engine_index=TargetEngine.NonPrimary,
-        ),
-        XK.XK_l: RewriteKeyEventAction(
-            keysym=XK.XK_Right,
-            target_engine_index=TargetEngine.NonPrimary,
-        ),
-        XK.XK_slash: RewriteKeyEventAction(
-            keysym=XK.XK_Control_L,
-            target_engine_index=TargetEngine.NonPrimary,
-        ),
-        XK.XK_n: RewriteKeyEventAction(
-            keysym=XK.XK_Delete,
-            target_engine_index=TargetEngine.NonPrimary,
-        ),
-        XK.XK_space: RewriteKeyEventAction(
-            keysym=XK.XK_Control_L,
-            target_engine_index=TargetEngine.All,
-        ),
+        XK.XK_w:         RewriteKeyEventAction(keysym=XK.XK_Up,         target_engine_index=0),
+        XK.XK_a:         RewriteKeyEventAction(keysym=XK.XK_Left,       target_engine_index=0),
+        XK.XK_s:         RewriteKeyEventAction(keysym=XK.XK_Down,       target_engine_index=0),
+        XK.XK_d:         RewriteKeyEventAction(keysym=XK.XK_Right,      target_engine_index=0),
+        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_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_space:     RewriteKeyEventAction(keysym=XK.XK_Control_L,  target_engine_index=TargetEngine.All),
         XK.XK_e: SelectGagAction(factor_x=0.038, factor_y=-0.047),  # elephant trunk
         XK.XK_f: SelectGagAction(factor_x=0.119, factor_y=-0.047),  # foghorn
     }
@@ -122,7 +102,7 @@ class ExtendedControls:
             = ToggleExtendedControlsAction()
         self._default_action = ForwardKeyEventAction()
         self._primary_engine_window = None
-        self._other_engine_windows = None
+        self._engine_windows_by_target_index = None
         self._active_key_registry = {}
         self._enabled = False
 
@@ -195,7 +175,7 @@ class ExtendedControls:
                 )
         self._enabled = True
         # reset cache
-        self._other_engine_windows = None
+        self._engine_windows_by_target_index = None
         print("INFO Enabled Extended Controls")
 
     def disable(self):
@@ -232,18 +212,27 @@ class ExtendedControls:
     def _ungrab_key(self, keycode):
         self.primary_engine_window.ungrab_key(keycode, X.AnyModifier)
 
-    def find_other_engine_windows(self):
+    def find_engine_windows(self):
         return x_find_window(
             self.xdisplay.screen().root,
-            lambda w: w.get_wm_name() == TOONTOWN_WINDOW_NAME
-                    and w.id != self.primary_engine_window.id,
+            lambda w: w.get_wm_name() == TOONTOWN_WINDOW_NAME,
         )
 
     @property
-    def other_engine_windows(self):
-        if not self._other_engine_windows:
-            self._other_engine_windows = self.find_other_engine_windows()
-        return self._other_engine_windows
+    def engine_windows_by_target_index(self):
+        if not self._engine_windows_by_target_index:
+            win_by_index = {}
+            for target_index, win in enumerate(self.find_engine_windows()):
+                print('INFO engine window {} has no target index, assuming {}'.format(win.id, target_index))
+                if not target_index in win_by_index:
+                    win_by_index[target_index] = []
+                win_by_index[target_index].append(win)
+            self._engine_windows_by_target_index = win_by_index
+        return self._engine_windows_by_target_index
+
+    @property
+    def engine_windows(self):
+        return [w for g in self.engine_windows_by_target_index.values() for w in g]
 
     def _update_active_key_registry(self, xkeyevent):
         # see self._check_active_key_registry