diff --git a/keymapper/daemon.py b/keymapper/daemon.py index 84bd89d0..04ea0933 100644 --- a/keymapper/daemon.py +++ b/keymapper/daemon.py @@ -79,6 +79,10 @@ class Daemon: + + + + @@ -121,6 +125,11 @@ class Daemon: return self.injectors[device].stop_injecting() + del self.injectors[device] + + def is_injecting(self, device): + """Is this device being mapped?""" + return device in self.injectors def start_injecting(self, device, preset): """Start injecting the preset for the device. diff --git a/keymapper/gtk/window.py b/keymapper/gtk/window.py index 4642dc6c..350fb7d8 100755 --- a/keymapper/gtk/window.py +++ b/keymapper/gtk/window.py @@ -241,9 +241,7 @@ class Window: CTX_APPLY, 'Applied the system default' ) - # restart reading because after injecting the device landscape - # changes a bit - keycode_reader.start_reading(self.selected_device) + GLib.timeout_add(10, self.show_device_mapping_status) def on_save_preset_clicked(self, button): """Save changes to a preset to the file system.""" @@ -301,6 +299,7 @@ class Window: # restart reading because after injecting the device landscape # changes a bit keycode_reader.start_reading(self.selected_device) + GLib.timeout_add(10, self.show_device_mapping_status) def on_preset_autoload_switch_activate(self, _, active): """Load the preset automatically next time the user logs in.""" @@ -326,9 +325,17 @@ class Window: self.selected_preset = None self.populate_presets() - GLib.idle_add( - lambda: keycode_reader.start_reading(self.selected_device) - ) + GLib.idle_add(lambda: keycode_reader.start_reading(device)) + + self.show_device_mapping_status() + + def show_device_mapping_status(self): + """Figure out if this device is currently under keymappers control.""" + if self.dbus.is_injecting(self.selected_device): + logger.info('This device is currently mapped.') + self.get('apply_system_layout').set_opacity(1) + else: + self.get('apply_system_layout').set_opacity(0.4) def on_create_preset_clicked(self, _): """Create a new preset and select it.""" diff --git a/tests/testcases/test_daemon.py b/tests/testcases/test_daemon.py index 045f4e75..d5b88776 100644 --- a/tests/testcases/test_daemon.py +++ b/tests/testcases/test_daemon.py @@ -79,25 +79,58 @@ class TestDaemon(unittest.TestCase): config.clear_config() def test_daemon(self): - keycode_from = 9 - keycode_to = 100 + keycode_from_1 = 9 + keycode_to_1 = 100 + keycode_from_2 = 12 + keycode_to_2 = 100 - custom_mapping.change(keycode_from, 'a') + custom_mapping.change(keycode_from_1, 'a') + custom_mapping.change(keycode_from_2, 'b') clear_system_mapping() - system_mapping['a'] = keycode_to + system_mapping['a'] = keycode_to_1 + system_mapping['b'] = keycode_to_2 - custom_mapping.save('device 2', 'foo') - config.set_autoload_preset('device 2', 'foo') + preset = 'foo' + + custom_mapping.save('device 2', preset) + config.set_autoload_preset('device 2', preset) pending_events['device 2'] = [ - Event(evdev.events.EV_KEY, keycode_from - 8, 0) + Event(evdev.events.EV_KEY, keycode_from_1 - 8, 0), ] self.daemon = Daemon() + # starts mapping right after creation + + self.assertTrue(self.daemon.is_injecting('device 2')) + self.assertFalse(self.daemon.is_injecting('device 1')) + + event = uinput_write_history_pipe[0].recv() + self.assertEqual(event.type, evdev.events.EV_KEY) + self.assertEqual(event.code, keycode_to_1 - 8) + self.assertEqual(event.value, 0) + + self.daemon.stop_injecting('device 2') + self.assertFalse(self.daemon.is_injecting('device 2')) + + pending_events['device 2'] = [ + Event(evdev.events.EV_KEY, keycode_from_2 - 8, 1), + Event(evdev.events.EV_KEY, keycode_from_2 - 8, 0), + ] + + time.sleep(0.2) + self.assertFalse(uinput_write_history_pipe[0].poll()) + + self.daemon.start_injecting('device 2', preset) + + event = uinput_write_history_pipe[0].recv() + self.assertEqual(event.type, evdev.events.EV_KEY) + self.assertEqual(event.code, keycode_to_2 - 8) + self.assertEqual(event.value, 1) event = uinput_write_history_pipe[0].recv() self.assertEqual(event.type, evdev.events.EV_KEY) - self.assertEqual(event.code, keycode_to - 8) + self.assertEqual(event.code, keycode_to_2 - 8) self.assertEqual(event.value, 0) diff --git a/tests/testcases/test_integration.py b/tests/testcases/test_integration.py index 5d5ccb96..3955e1c0 100644 --- a/tests/testcases/test_integration.py +++ b/tests/testcases/test_integration.py @@ -112,6 +112,11 @@ class TestIntegration(unittest.TestCase): def get_rows(self): return self.window.get('key_list').get_children() + def test_show_device_mapping_status(self): + # this function may not return True, otherwise the timeout + # runs forever + self.assertFalse(self.window.show_device_mapping_status()) + def test_autoload(self): self.window.on_preset_autoload_switch_activate(None, False) self.assertFalse(config.is_autoloaded(