From ab56263c3b9bb3dc159c8f6553f4c7ffffce7d76 Mon Sep 17 00:00:00 2001 From: sezanzeb Date: Wed, 16 Dec 2020 12:57:09 +0100 Subject: [PATCH] improved numlock correction --- keymapper/dev/injector.py | 22 +++++++++++++++------- tests/testcases/test_injector.py | 13 +++++++++---- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/keymapper/dev/injector.py b/keymapper/dev/injector.py index 945bdc1d..0e6be736 100644 --- a/keymapper/dev/injector.py +++ b/keymapper/dev/injector.py @@ -58,10 +58,15 @@ def is_numlock_on(): return False -def toggle_numlock(): - """Turn the numlock on or off.""" +def set_numlock(state): + """Set the numlock to a given state of True or False.""" + value = { + True: 'on', + False: 'off' + }[state] + try: - subprocess.check_output(['numlockx', 'toggle']) + subprocess.check_output(['numlockx', value]) except FileNotFoundError: # doesn't seem to be installed everywhere logger.debug('numlockx not found') @@ -74,10 +79,7 @@ def ensure_numlock(func): # remember it and apply back later numlock_before = is_numlock_on() result = func(*args, **kwargs) - numlock_after = is_numlock_on() - if numlock_after != numlock_before: - logger.debug('Reverting numlock status to %s', numlock_before) - toggle_numlock() + set_numlock(numlock_before) return result return wrapped @@ -282,6 +284,8 @@ class KeycodeInjector: Stuff is non-blocking by using asyncio in order to do multiple things somewhat concurrently. """ + numlock_state = is_numlock_on() + loop = asyncio.get_event_loop() coroutines = [] @@ -345,6 +349,10 @@ class KeycodeInjector: coroutines.append(self._msg_listener(loop)) + # set the numlock state to what it was before injecting, because + # grabbing devices screws this up + set_numlock(numlock_state) + try: loop.run_until_complete(asyncio.gather(*coroutines)) except RuntimeError: diff --git a/tests/testcases/test_injector.py b/tests/testcases/test_injector.py index f081be79..31b5721f 100644 --- a/tests/testcases/test_injector.py +++ b/tests/testcases/test_injector.py @@ -26,7 +26,7 @@ import copy import evdev from evdev.ecodes import EV_REL, EV_KEY, EV_ABS, ABS_HAT0X -from keymapper.dev.injector import is_numlock_on, toggle_numlock, \ +from keymapper.dev.injector import is_numlock_on, set_numlock, \ ensure_numlock, KeycodeInjector from keymapper.state import custom_mapping, system_mapping from keymapper.mapping import Mapping @@ -212,12 +212,12 @@ class TestInjector(unittest.TestCase): def test_numlock(self): before = is_numlock_on() - toggle_numlock() # should change + set_numlock(not before) # should change self.assertEqual(not before, is_numlock_on()) @ensure_numlock def wrapped_1(): - toggle_numlock() + set_numlock(not is_numlock_on()) @ensure_numlock def wrapped_2(): @@ -230,7 +230,7 @@ class TestInjector(unittest.TestCase): self.assertEqual(not before, is_numlock_on()) # toggle one more time to restore the previous configuration - toggle_numlock() + set_numlock(before) self.assertEqual(before, is_numlock_on()) def test_abs_to_rel(self): @@ -290,6 +290,8 @@ class TestInjector(unittest.TestCase): self.assertAlmostEqual(history[-2][2], -1) def test_injector(self): + numlock_before = is_numlock_on() + custom_mapping.change((EV_KEY, 8), 'k(KEY_Q).k(w)') custom_mapping.change((EV_ABS, ABS_HAT0X), 'a') # one mapping that is unknown in the system_mapping on purpose @@ -373,6 +375,9 @@ class TestInjector(unittest.TestCase): time.sleep(0.1) self.assertTrue(self.injector._process.is_alive()) + numlock_after = is_numlock_on() + self.assertEqual(numlock_before, numlock_after) + if __name__ == "__main__": unittest.main()