From bc32099486be18336d32d6b9d2c99cbbfe2cc61c Mon Sep 17 00:00:00 2001 From: sezanzeb Date: Sat, 5 Dec 2020 12:05:17 +0100 Subject: [PATCH] some improvements on the hold functionality --- README.md | 1 + keymapper/dev/keycode_mapper.py | 5 +++-- keymapper/dev/macros.py | 22 +++++++++------------- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index ba7d33d9..273b0637 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ Documentation: - `w` waits in milliseconds - `k` writes a single keystroke - `m` holds a modifier while executing the second parameter +- `h` executes the parameter as long as the key is pressed down - `.` executes two actions behind each other Syntax errors are logged to the console. diff --git a/keymapper/dev/keycode_mapper.py b/keymapper/dev/keycode_mapper.py index f5ee2307..c3f51e09 100644 --- a/keymapper/dev/keycode_mapper.py +++ b/keymapper/dev/keycode_mapper.py @@ -30,7 +30,8 @@ from keymapper.logger import logger from keymapper.dev.ev_abs_mapper import JOYSTICK -# maps mouse buttons to running macros +# maps mouse buttons to macro instances that have been executed. They may +# still be running or already be done. active_macros = {} @@ -92,7 +93,7 @@ def handle_keycode(code_to_code, macros, event, uinput): macro = macros[input_keycode] active_macros[input_keycode] = macro # TODO test that holding is true - macro.holding = True + macro.press_key() logger.spam( 'got code:%s value:%s, maps to macro %s', input_keycode, diff --git a/keymapper/dev/macros.py b/keymapper/dev/macros.py index 7f46f56e..bddf4971 100644 --- a/keymapper/dev/macros.py +++ b/keymapper/dev/macros.py @@ -73,7 +73,6 @@ class _Macro: self.tasks = [] self.handler = lambda *args: logger.error('No handler set') self.code = code - self.running = False # supposed to be True between key event values 1 (down) and 0 (up) self.holding = False @@ -107,40 +106,37 @@ class _Macro: async def run(self): """Run the macro.""" - self.running = True - for task_type, task in self.tasks: - if not self.running: - logger.debug('Macro execution stopped') - break - coroutine = task() if asyncio.iscoroutine(coroutine): await coroutine - def stop(self): - """Stop the macro.""" + def press_key(self): + """Tell all child macros that the key was pressed down.""" # TODO test - self.running = False + self.holding = True + for macro in self.child_macros: + macro.press_key() def release_key(self): """Tell all child macros that the key was released.""" + # TODO test self.holding = False for macro in self.child_macros: macro.release_key() def hold(self, macro): """Loops the execution until key release.""" + # TODO test. especially make sure that this doesn't loop forever + # even with complicated macros and weird calls to press and release if not isinstance(macro, _Macro): raise ValueError( 'Expected the param for hold to be ' f'a macro, but got "{macro}"' ) - # TODO test - async def task(): - while self.holding and self.running: + while self.holding: await macro.run() self.tasks.append((REPEAT, task))