mirror of
https://github.com/sezanzeb/input-remapper
synced 2024-11-12 01:10:38 +00:00
unsaved changes dialog
This commit is contained in:
parent
20dbb4c8a8
commit
80bd7deacd
@ -238,7 +238,8 @@
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-7">go_back</action-widget>
|
||||
<action-widget response="-3">go_back</action-widget>
|
||||
<action-widget response="-6">go_ahead</action-widget>
|
||||
</action-widgets>
|
||||
<child type="titlebar">
|
||||
<placeholder/>
|
||||
|
@ -203,8 +203,10 @@ def setxkbmap(device, layout):
|
||||
logger.info('Applying layout "%s" on device %s', layout, device)
|
||||
group = get_devices()[device]
|
||||
|
||||
keycodes = None if layout is None else 'key-mapper'
|
||||
layout = layout or get_system_layout()
|
||||
if layout is None:
|
||||
cmd = ['setxkbmap', '-layout', get_system_layout()]
|
||||
else:
|
||||
cmd = ['setxkbmap', '-layout', layout, '-keycodes', 'key-mapper']
|
||||
|
||||
# apply it to every device that hangs on the same usb port, because I
|
||||
# have no idea how to figure out which one of those 3 devices that are
|
||||
@ -214,17 +216,9 @@ def setxkbmap(device, layout):
|
||||
# only all virtual devices of the same hardware device
|
||||
continue
|
||||
|
||||
cmd = [
|
||||
'setxkbmap',
|
||||
'-device', str(xinput_id)
|
||||
]
|
||||
if layout is not None:
|
||||
cmd += ['-layout', layout]
|
||||
if keycodes is not None:
|
||||
cmd += ['-keycodes', keycodes]
|
||||
|
||||
logger.debug('Running `%s`', ' '.join(cmd))
|
||||
subprocess.run(cmd)
|
||||
device_cmd = cmd + ['-device', str(xinput_id)]
|
||||
logger.debug('Running `%s`', ' '.join(device_cmd))
|
||||
subprocess.run(device_cmd, capture_output=True)
|
||||
|
||||
|
||||
def create_identity_mapping():
|
||||
|
@ -36,20 +36,18 @@ from keymapper.linux import keycode_reader
|
||||
CTX_KEYCODE = 2
|
||||
|
||||
|
||||
class Row:
|
||||
class Row(Gtk.ListBoxRow):
|
||||
"""A single, configurable key mapping."""
|
||||
__gtype_name__ = 'ListBoxRow'
|
||||
|
||||
def __init__(self, delete_callback, window, keycode=None, character=None):
|
||||
"""Construct a row widget."""
|
||||
self.widget = None
|
||||
super().__init__()
|
||||
self.device = window.selected_device
|
||||
self.window = window
|
||||
self.delete_callback = delete_callback
|
||||
self.put_together(keycode, character)
|
||||
|
||||
def get_widget(self):
|
||||
"""Return the widget that wraps all the widgets of the row."""
|
||||
return self.widget
|
||||
|
||||
def get_keycode(self):
|
||||
keycode = self.keycode.get_label()
|
||||
return int(keycode) if keycode else None
|
||||
@ -111,7 +109,7 @@ class Row:
|
||||
|
||||
def highlight(self):
|
||||
"""Mark this row as changed."""
|
||||
self.widget.get_style_context().add_class('changed')
|
||||
self.get_style_context().add_class('changed')
|
||||
|
||||
def on_character_input_change(self, entry):
|
||||
keycode = self.get_keycode()
|
||||
@ -169,11 +167,9 @@ class Row:
|
||||
box.pack_start(delete_button, expand=True, fill=False, padding=0)
|
||||
box.show_all()
|
||||
|
||||
row = Gtk.ListBoxRow()
|
||||
row.add(box)
|
||||
row.show_all()
|
||||
self.add(box)
|
||||
self.show_all()
|
||||
|
||||
self.widget = row
|
||||
self.character_input = character_input
|
||||
self.keycode = keycode_input
|
||||
|
||||
|
@ -34,13 +34,16 @@ CONTINUE = True
|
||||
GO_BACK = False
|
||||
|
||||
|
||||
def unsavedChangesDialog():
|
||||
def unsaved_changes_dialog():
|
||||
"""Blocks until the user decided about an action."""
|
||||
gladefile = get_data_path('key-mapper.glade')
|
||||
builder = Gtk.Builder()
|
||||
builder.add_from_file(gladefile)
|
||||
dialog = builder.get_object('unsaved_changes')
|
||||
dialog.show()
|
||||
dialog.run()
|
||||
response = dialog.run()
|
||||
dialog.hide()
|
||||
# TODO do something meaningful
|
||||
return GO_BACK
|
||||
if response == Gtk.ResponseType.ACCEPT:
|
||||
return CONTINUE
|
||||
else:
|
||||
return GO_BACK
|
||||
|
@ -35,7 +35,7 @@ from keymapper.presets import get_presets, find_newest_preset, \
|
||||
from keymapper.logger import logger
|
||||
from keymapper.linux import get_devices, keycode_reader
|
||||
from keymapper.gtk.row import Row
|
||||
from keymapper.gtk.unsaved import unsavedChangesDialog, GO_BACK
|
||||
from keymapper.gtk.unsaved import unsaved_changes_dialog, GO_BACK
|
||||
|
||||
|
||||
def gtk_iteration():
|
||||
@ -220,9 +220,12 @@ class Window:
|
||||
|
||||
def on_select_device(self, dropdown):
|
||||
"""List all presets, create one if none exist yet."""
|
||||
if custom_mapping.changed:
|
||||
if unsavedChangesDialog() == GO_BACK:
|
||||
return
|
||||
if dropdown.get_active_id() == self.selected_device:
|
||||
return
|
||||
|
||||
if custom_mapping.changed and unsaved_changes_dialog() == GO_BACK:
|
||||
dropdown.set_active_id(self.selected_device)
|
||||
return
|
||||
|
||||
device = dropdown.get_active_text()
|
||||
|
||||
@ -239,7 +242,7 @@ class Window:
|
||||
def on_create_preset_clicked(self, button):
|
||||
"""Create a new preset and select it."""
|
||||
if custom_mapping.changed:
|
||||
if unsavedChangesDialog() == GO_BACK:
|
||||
if unsaved_changes_dialog() == GO_BACK:
|
||||
return
|
||||
|
||||
new_preset = create_preset(self.selected_device)
|
||||
@ -249,9 +252,12 @@ class Window:
|
||||
|
||||
def on_select_preset(self, dropdown):
|
||||
"""Show the mappings of the preset."""
|
||||
if custom_mapping.changed:
|
||||
if unsavedChangesDialog() == GO_BACK:
|
||||
return
|
||||
if dropdown.get_active_id() == self.selected_preset:
|
||||
return
|
||||
|
||||
if custom_mapping.changed and unsaved_changes_dialog() == GO_BACK:
|
||||
dropdown.set_active_id(self.selected_preset)
|
||||
return
|
||||
|
||||
self.clear_mapping_table()
|
||||
|
||||
@ -269,7 +275,7 @@ class Window:
|
||||
keycode=keycode,
|
||||
character=character
|
||||
)
|
||||
key_list.insert(single_key_mapping.get_widget(), -1)
|
||||
key_list.insert(single_key_mapping, -1)
|
||||
|
||||
self.add_empty()
|
||||
|
||||
@ -279,7 +285,7 @@ class Window:
|
||||
delete_callback=self.on_row_removed
|
||||
)
|
||||
key_list = self.get('key_list')
|
||||
key_list.insert(empty.get_widget(), -1)
|
||||
key_list.insert(empty, -1)
|
||||
|
||||
def on_row_removed(self, single_key_mapping):
|
||||
"""Stuff to do when a row was removed
|
||||
@ -290,7 +296,7 @@ class Window:
|
||||
"""
|
||||
key_list = self.get('key_list')
|
||||
# https://stackoverflow.com/a/30329591/4417769
|
||||
key_list.remove(single_key_mapping.get_widget())
|
||||
key_list.remove(single_key_mapping)
|
||||
|
||||
def save_config(self):
|
||||
"""Write changes to disk"""
|
||||
|
@ -55,6 +55,10 @@ linux._devices = {
|
||||
}
|
||||
linux.get_devices = lambda: linux._devices
|
||||
|
||||
# don't block tests
|
||||
from keymapper.gtk import unsaved
|
||||
unsaved.unsaved_changes_dialog = lambda: unsaved.CONTINUE
|
||||
|
||||
from keymapper.logger import update_verbosity
|
||||
|
||||
# some class function stubs.
|
||||
@ -73,7 +77,7 @@ if __name__ == "__main__":
|
||||
# in all of the available tests like unittest.main() does...,
|
||||
# so provide both options.
|
||||
if len(modules) > 0:
|
||||
# for example `tests/test.py ConfigTest.testFirstLine`
|
||||
# for example `tests/test.py integration.Integration.test_can_start`
|
||||
testsuite = unittest.defaultTestLoader.loadTestsFromNames(
|
||||
[f'testcases.{module}' for module in modules]
|
||||
)
|
||||
|
@ -124,6 +124,9 @@ class Integration(unittest.TestCase):
|
||||
def get_active_text(self):
|
||||
return self.name
|
||||
|
||||
def get_active_id(self):
|
||||
return self.name
|
||||
|
||||
# created on start because the first device is selected and some empty
|
||||
# preset prepared.
|
||||
self.assertTrue(os.path.exists(f'{USERS_SYMBOLS}/device_1/new_preset'))
|
||||
|
Loading…
Reference in New Issue
Block a user