better support for ttys

This commit is contained in:
sezanzeb 2020-12-19 22:58:36 +01:00
parent 4dab8059e9
commit f96dcb7ed3
5 changed files with 66 additions and 19 deletions

View File

@ -541,7 +541,7 @@
<object class="GtkSwitch" id="preset_autoload_switch">
<property name="visible">True</property>
<property name="can-focus">True</property>
<signal name="state-set" handler="on_preset_autoload_switch_activate" swapped="no"/>
<signal name="state-set" handler="on_autoload_switch" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>

View File

@ -195,6 +195,10 @@ class GlobalConfig(ConfigBase):
if preset is not None:
self.set(f'autoload.{device}', preset)
else:
logger.info(
'Not loading injecting for "%s" automatically anmore',
device
)
self.remove(f'autoload.{device}')
def iterate_autoload_presets(self):

View File

@ -46,20 +46,27 @@ CLOSE = 0
def is_numlock_on():
"""Get the current state of the numlock."""
xset_q = subprocess.check_output(['xset', 'q']).decode()
num_lock_status = re.search(
r'Num Lock:\s+(.+?)\s',
xset_q
)
try:
xset_q = subprocess.check_output(['xset', 'q']).decode()
num_lock_status = re.search(
r'Num Lock:\s+(.+?)\s',
xset_q
)
if num_lock_status is not None:
return num_lock_status[1] == 'on'
if num_lock_status is not None:
return num_lock_status[1] == 'on'
return False
return False
except subprocess.CalledProcessError:
# tty
return None
def set_numlock(state):
"""Set the numlock to a given state of True or False."""
if state is None:
return
value = {
True: 'on',
False: 'off'
@ -81,8 +88,11 @@ def ensure_numlock(func):
# for some reason, grabbing a device can modify the num lock state.
# remember it and apply back later
numlock_before = is_numlock_on()
result = func(*args, **kwargs)
set_numlock(numlock_before)
return result
return wrapped

View File

@ -70,6 +70,22 @@ def get_selected_row_bg():
return color.to_string()
class HandlerDisabled:
"""Safely modify a widget without causing handlers to be called.
Use in a with statement.
"""
def __init__(self, widget, handler):
self.widget = widget
self.handler = handler
def __enter__(self):
self.widget.handler_block_by_func(self.handler)
def __exit__(self, *_):
self.widget.handler_unblock_by_func(self.handler)
class Window:
"""User Interface."""
def __init__(self):
@ -358,7 +374,7 @@ class Window:
keycode_reader.start_reading(device)
GLib.timeout_add(10, self.show_device_mapping_status)
def on_preset_autoload_switch_activate(self, _, active):
def on_autoload_switch(self, _, active):
"""Load the preset automatically next time the user logs in."""
device = self.selected_device
preset = self.selected_preset
@ -442,10 +458,12 @@ class Window:
key_list.insert(single_key_mapping, -1)
autoload_switch = self.get('preset_autoload_switch')
autoload_switch.set_active(config.is_autoloaded(
self.selected_device,
self.selected_preset
))
with HandlerDisabled(autoload_switch, self.on_autoload_switch):
autoload_switch.set_active(config.is_autoloaded(
self.selected_device,
self.selected_preset
))
self.get('preset_name_input').set_text('')
self.add_empty()

View File

@ -122,15 +122,20 @@ class TestIntegration(unittest.TestCase):
self.assertFalse(self.window.show_device_mapping_status())
def test_autoload(self):
self.window.on_preset_autoload_switch_activate(None, False)
self.window.on_autoload_switch(None, False)
self.assertFalse(config.is_autoloaded(
self.window.selected_device,
self.window.selected_preset
))
# select a preset for the first device
self.window.on_select_device(FakeDropdown('device 1'))
self.window.on_preset_autoload_switch_activate(None, True)
gtk_iteration()
self.assertFalse(self.window.get('preset_autoload_switch').get_active())
# select a preset for the first device
self.window.get('preset_autoload_switch').set_active(True)
gtk_iteration()
self.assertTrue(self.window.get('preset_autoload_switch').get_active())
self.assertTrue(config.is_autoloaded('device 1', 'new preset'))
self.assertFalse(config.is_autoloaded('device 2', 'new preset'))
self.assertListEqual(
@ -138,9 +143,18 @@ class TestIntegration(unittest.TestCase):
[('device 1', 'new preset')]
)
# switch the preset, the switch should be correct and the config
# not changed.
self.window.on_create_preset_clicked(None)
gtk_iteration()
self.assertEqual(self.window.selected_preset, 'new preset 2')
self.assertFalse(self.window.get('preset_autoload_switch').get_active())
self.assertTrue(config.is_autoloaded('device 1', 'new preset'))
# select a preset for the second device
self.window.on_select_device(FakeDropdown('device 2'))
self.window.on_preset_autoload_switch_activate(None, True)
self.window.get('preset_autoload_switch').set_active(True)
gtk_iteration()
self.assertTrue(config.is_autoloaded('device 1', 'new preset'))
self.assertTrue(config.is_autoloaded('device 2', 'new preset'))
self.assertListEqual(
@ -149,7 +163,8 @@ class TestIntegration(unittest.TestCase):
)
# disable autoloading for the second device
self.window.on_preset_autoload_switch_activate(None, False)
self.window.get('preset_autoload_switch').set_active(False)
gtk_iteration()
self.assertTrue(config.is_autoloaded('device 1', 'new preset'))
self.assertFalse(config.is_autoloaded('device 2', 'new preset'))
self.assertListEqual(