mirror of
https://github.com/sezanzeb/input-remapper
synced 2024-11-08 07:10:36 +00:00
obsolete reverse mapping
This commit is contained in:
parent
6771e8d8dc
commit
c95559e554
@ -435,6 +435,7 @@ class KeycodeInjector:
|
|||||||
else:
|
else:
|
||||||
# TODO compile int-int mapping instead of going this route.
|
# TODO compile int-int mapping instead of going this route.
|
||||||
# I think that makes the reverse mapping obsolete.
|
# I think that makes the reverse mapping obsolete.
|
||||||
|
# It already is actually.
|
||||||
target_keycode = system_mapping.get(character)
|
target_keycode = system_mapping.get(character)
|
||||||
if target_keycode is None:
|
if target_keycode is None:
|
||||||
logger.error(
|
logger.error(
|
||||||
|
@ -30,14 +30,6 @@ from keymapper.logger import logger
|
|||||||
from keymapper.paths import get_config_path, touch
|
from keymapper.paths import get_config_path, touch
|
||||||
|
|
||||||
|
|
||||||
def keep_reverse_mapping_intact(func):
|
|
||||||
"""Decorator for Mapping.update_reverse_mapping."""
|
|
||||||
def wrapper(self, *args, **kwargs):
|
|
||||||
func(self, *args, **kwargs)
|
|
||||||
self.update_reverse_mapping()
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
|
|
||||||
class Mapping:
|
class Mapping:
|
||||||
"""Contains and manages mappings.
|
"""Contains and manages mappings.
|
||||||
|
|
||||||
@ -47,13 +39,6 @@ class Mapping:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._mapping = {}
|
self._mapping = {}
|
||||||
|
|
||||||
# Maintain this second mapping in order to optimize get_keycode.
|
|
||||||
# This mapping is not complete, since multiple keycodes can map
|
|
||||||
# to the same character in _mapping which is not possible in
|
|
||||||
# _reverse_mapping! It is based on _reverse_mapping and
|
|
||||||
# reconstructed on changes.
|
|
||||||
self._reverse_mapping = {}
|
|
||||||
|
|
||||||
self.changed = False
|
self.changed = False
|
||||||
|
|
||||||
self.config = {}
|
self.config = {}
|
||||||
@ -65,18 +50,6 @@ class Mapping:
|
|||||||
def __len__(self):
|
def __len__(self):
|
||||||
return len(self._mapping)
|
return len(self._mapping)
|
||||||
|
|
||||||
def update_reverse_mapping(self):
|
|
||||||
"""Generate a reverse mapping to optimize reverse lookups.
|
|
||||||
|
|
||||||
If _mapping contains `20: "a, A"` (the xkb syntax for modified keys),
|
|
||||||
reverse mapping will contain `"a": 20, "A": 20`.
|
|
||||||
"""
|
|
||||||
self._reverse_mapping = {}
|
|
||||||
for key, value in self._mapping.items():
|
|
||||||
for character in value.split(','):
|
|
||||||
self._reverse_mapping[character.strip()] = key
|
|
||||||
|
|
||||||
@keep_reverse_mapping_intact
|
|
||||||
def change(self, new_keycode, character, previous_keycode=None):
|
def change(self, new_keycode, character, previous_keycode=None):
|
||||||
"""Replace the mapping of a keycode with a different one.
|
"""Replace the mapping of a keycode with a different one.
|
||||||
|
|
||||||
@ -115,7 +88,6 @@ class Mapping:
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@keep_reverse_mapping_intact
|
|
||||||
def clear(self, keycode):
|
def clear(self, keycode):
|
||||||
"""Remove a keycode from the mapping.
|
"""Remove a keycode from the mapping.
|
||||||
|
|
||||||
@ -127,13 +99,11 @@ class Mapping:
|
|||||||
del self._mapping[keycode]
|
del self._mapping[keycode]
|
||||||
self.changed = True
|
self.changed = True
|
||||||
|
|
||||||
@keep_reverse_mapping_intact
|
|
||||||
def empty(self):
|
def empty(self):
|
||||||
"""Remove all mappings."""
|
"""Remove all mappings."""
|
||||||
self._mapping = {}
|
self._mapping = {}
|
||||||
self.changed = True
|
self.changed = True
|
||||||
|
|
||||||
@keep_reverse_mapping_intact
|
|
||||||
def load(self, device, preset):
|
def load(self, device, preset):
|
||||||
"""Load a dumped JSON from home to overwrite the mappings."""
|
"""Load a dumped JSON from home to overwrite the mappings."""
|
||||||
path = get_config_path(device, preset)
|
path = get_config_path(device, preset)
|
||||||
@ -169,7 +139,6 @@ class Mapping:
|
|||||||
"""Create a copy of the mapping."""
|
"""Create a copy of the mapping."""
|
||||||
mapping = Mapping()
|
mapping = Mapping()
|
||||||
mapping._mapping = copy.deepcopy(self._mapping)
|
mapping._mapping = copy.deepcopy(self._mapping)
|
||||||
mapping.update_reverse_mapping()
|
|
||||||
mapping.changed = self.changed
|
mapping.changed = self.changed
|
||||||
return mapping
|
return mapping
|
||||||
|
|
||||||
@ -191,14 +160,6 @@ class Mapping:
|
|||||||
|
|
||||||
self.changed = False
|
self.changed = False
|
||||||
|
|
||||||
def get_keycode(self, character):
|
|
||||||
"""Get the keycode for that character.
|
|
||||||
|
|
||||||
If multiple keycodes map to that character, an arbitrary one of
|
|
||||||
those is returned.
|
|
||||||
"""
|
|
||||||
return self._reverse_mapping.get(character)
|
|
||||||
|
|
||||||
def get_character(self, keycode):
|
def get_character(self, keycode):
|
||||||
"""Read the character that is mapped to this keycode.
|
"""Read the character that is mapped to this keycode.
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ class TestIntegration(unittest.TestCase):
|
|||||||
gtk_iteration()
|
gtk_iteration()
|
||||||
self.assertEqual(len(self.window.get('key_list').get_children()), 2)
|
self.assertEqual(len(self.window.get('key_list').get_children()), 2)
|
||||||
|
|
||||||
self.assertEqual(custom_mapping.get_keycode('Shift_L'), 30)
|
self.assertEqual(custom_mapping.get_character(30), 'Shift_L')
|
||||||
self.assertEqual(row.get_character(), 'Shift_L')
|
self.assertEqual(row.get_character(), 'Shift_L')
|
||||||
self.assertEqual(row.get_keycode(), 30)
|
self.assertEqual(row.get_keycode(), 30)
|
||||||
|
|
||||||
@ -295,7 +295,6 @@ class TestIntegration(unittest.TestCase):
|
|||||||
# try to add a duplicate keycode, it should be ignored
|
# try to add a duplicate keycode, it should be ignored
|
||||||
self.change_empty_row(11, 'd', success=False)
|
self.change_empty_row(11, 'd', success=False)
|
||||||
self.assertEqual(custom_mapping.get_character(11), 'k(b).k(c)')
|
self.assertEqual(custom_mapping.get_character(11), 'k(b).k(c)')
|
||||||
self.assertIsNone(custom_mapping.get_keycode('d'))
|
|
||||||
# and the number of rows shouldn't change
|
# and the number of rows shouldn't change
|
||||||
self.assertEqual(len(self.get_rows()), num_rows_target)
|
self.assertEqual(len(self.get_rows()), num_rows_target)
|
||||||
|
|
||||||
@ -313,12 +312,10 @@ class TestIntegration(unittest.TestCase):
|
|||||||
self.assertEqual(len(self.get_rows()), 3)
|
self.assertEqual(len(self.get_rows()), 3)
|
||||||
|
|
||||||
self.assertEqual(custom_mapping.get_character(11), 'b')
|
self.assertEqual(custom_mapping.get_character(11), 'b')
|
||||||
self.assertEqual(custom_mapping.get_keycode('b'), 11)
|
|
||||||
|
|
||||||
def remove(row, code, char, num_rows_after):
|
def remove(row, code, char, num_rows_after):
|
||||||
if code is not None and char is not None:
|
if code is not None and char is not None:
|
||||||
self.assertEqual(custom_mapping.get_character(code), char)
|
self.assertEqual(custom_mapping.get_character(code), char)
|
||||||
self.assertEqual(custom_mapping.get_keycode(char), code)
|
|
||||||
self.assertEqual(row.get_character(), char)
|
self.assertEqual(row.get_character(), char)
|
||||||
self.assertEqual(row.get_keycode(), code)
|
self.assertEqual(row.get_keycode(), code)
|
||||||
row.on_delete_button_clicked()
|
row.on_delete_button_clicked()
|
||||||
@ -326,7 +323,6 @@ class TestIntegration(unittest.TestCase):
|
|||||||
gtk_iteration()
|
gtk_iteration()
|
||||||
self.assertIsNone(row.get_keycode())
|
self.assertIsNone(row.get_keycode())
|
||||||
self.assertIsNone(row.get_character())
|
self.assertIsNone(row.get_character())
|
||||||
self.assertIsNone(custom_mapping.get_keycode(char))
|
|
||||||
self.assertIsNone(custom_mapping.get_character(code))
|
self.assertIsNone(custom_mapping.get_character(code))
|
||||||
self.assertEqual(len(self.get_rows()), num_rows_after)
|
self.assertEqual(len(self.get_rows()), num_rows_after)
|
||||||
|
|
||||||
|
@ -46,14 +46,10 @@ class TestMapping(unittest.TestCase):
|
|||||||
mapping1.change(2, 'b')
|
mapping1.change(2, 'b')
|
||||||
|
|
||||||
self.assertEqual(mapping1.get_character(1), 'a')
|
self.assertEqual(mapping1.get_character(1), 'a')
|
||||||
self.assertEqual(mapping1.get_keycode('a'), 1)
|
|
||||||
self.assertEqual(mapping1.get_character(2), 'b')
|
self.assertEqual(mapping1.get_character(2), 'b')
|
||||||
self.assertEqual(mapping1.get_keycode('b'), 2)
|
|
||||||
|
|
||||||
self.assertEqual(mapping2.get_character(1), 'a')
|
self.assertEqual(mapping2.get_character(1), 'a')
|
||||||
self.assertEqual(mapping2.get_keycode('a'), 1)
|
|
||||||
self.assertIsNone(mapping2.get_character(2))
|
self.assertIsNone(mapping2.get_character(2))
|
||||||
self.assertIsNone(mapping2.get_keycode('b'))
|
|
||||||
|
|
||||||
def test_save_load(self):
|
def test_save_load(self):
|
||||||
self.mapping.change(10, '1')
|
self.mapping.change(10, '1')
|
||||||
@ -67,15 +63,6 @@ class TestMapping(unittest.TestCase):
|
|||||||
self.assertEqual(loaded.get_character(10), '1')
|
self.assertEqual(loaded.get_character(10), '1')
|
||||||
self.assertEqual(loaded.get_character(11), '2')
|
self.assertEqual(loaded.get_character(11), '2')
|
||||||
self.assertEqual(loaded.get_character(12), '3')
|
self.assertEqual(loaded.get_character(12), '3')
|
||||||
self.assertEqual(loaded.get_keycode('1'), 10)
|
|
||||||
self.assertEqual(loaded.get_keycode('2'), 11)
|
|
||||||
self.assertEqual(loaded.get_keycode('3'), 12)
|
|
||||||
|
|
||||||
def test_split(self):
|
|
||||||
# mapping supports the xmodmap/xkb syntax for modified buttons
|
|
||||||
self.mapping.change(10, 'a, A')
|
|
||||||
self.assertEqual(self.mapping.get_keycode('a'), 10)
|
|
||||||
self.assertEqual(self.mapping.get_keycode('A'), 10)
|
|
||||||
|
|
||||||
def test_change(self):
|
def test_change(self):
|
||||||
# 1 is not assigned yet, ignore it
|
# 1 is not assigned yet, ignore it
|
||||||
@ -83,39 +70,33 @@ class TestMapping(unittest.TestCase):
|
|||||||
self.assertTrue(self.mapping.changed)
|
self.assertTrue(self.mapping.changed)
|
||||||
self.assertIsNone(self.mapping.get_character(1))
|
self.assertIsNone(self.mapping.get_character(1))
|
||||||
self.assertEqual(self.mapping.get_character(2), 'a')
|
self.assertEqual(self.mapping.get_character(2), 'a')
|
||||||
self.assertEqual(self.mapping.get_keycode('a'), 2)
|
|
||||||
self.assertEqual(len(self.mapping), 1)
|
self.assertEqual(len(self.mapping), 1)
|
||||||
|
|
||||||
# change 2 to 3 and change a to b
|
# change 2 to 3 and change a to b
|
||||||
self.mapping.change(3, 'b', 2)
|
self.mapping.change(3, 'b', 2)
|
||||||
self.assertIsNone(self.mapping.get_character(2))
|
self.assertIsNone(self.mapping.get_character(2))
|
||||||
self.assertEqual(self.mapping.get_character(3), 'b')
|
self.assertEqual(self.mapping.get_character(3), 'b')
|
||||||
self.assertEqual(self.mapping.get_keycode('b'), 3)
|
|
||||||
self.assertEqual(len(self.mapping), 1)
|
self.assertEqual(len(self.mapping), 1)
|
||||||
|
|
||||||
# add 4
|
# add 4
|
||||||
self.mapping.change(4, 'c', None)
|
self.mapping.change(4, 'c', None)
|
||||||
self.assertEqual(self.mapping.get_character(3), 'b')
|
self.assertEqual(self.mapping.get_character(3), 'b')
|
||||||
self.assertEqual(self.mapping.get_character(4), 'c')
|
self.assertEqual(self.mapping.get_character(4), 'c')
|
||||||
self.assertEqual(self.mapping.get_keycode('c'), 4)
|
|
||||||
self.assertEqual(len(self.mapping), 2)
|
self.assertEqual(len(self.mapping), 2)
|
||||||
|
|
||||||
# change the mapping of 4 to d
|
# change the mapping of 4 to d
|
||||||
self.mapping.change(4, 'd', None)
|
self.mapping.change(4, 'd', None)
|
||||||
self.assertEqual(self.mapping.get_character(4), 'd')
|
self.assertEqual(self.mapping.get_character(4), 'd')
|
||||||
self.assertEqual(self.mapping.get_keycode('d'), 4)
|
|
||||||
self.assertEqual(len(self.mapping), 2)
|
self.assertEqual(len(self.mapping), 2)
|
||||||
|
|
||||||
# this also works in the same way
|
# this also works in the same way
|
||||||
self.mapping.change(4, 'e', 4)
|
self.mapping.change(4, 'e', 4)
|
||||||
self.assertEqual(self.mapping.get_character(4), 'e')
|
self.assertEqual(self.mapping.get_character(4), 'e')
|
||||||
self.assertEqual(self.mapping.get_keycode('e'), 4)
|
|
||||||
self.assertEqual(len(self.mapping), 2)
|
self.assertEqual(len(self.mapping), 2)
|
||||||
|
|
||||||
# and this
|
# and this
|
||||||
self.mapping.change('4', 'f', '4')
|
self.mapping.change('4', 'f', '4')
|
||||||
self.assertEqual(self.mapping.get_character(4), 'f')
|
self.assertEqual(self.mapping.get_character(4), 'f')
|
||||||
self.assertEqual(self.mapping.get_keycode('f'), 4)
|
|
||||||
self.assertEqual(len(self.mapping), 2)
|
self.assertEqual(len(self.mapping), 2)
|
||||||
|
|
||||||
# non-int keycodes are ignored
|
# non-int keycodes are ignored
|
||||||
|
Loading…
Reference in New Issue
Block a user