obsolete reverse mapping

This commit is contained in:
sezanzeb 2020-12-02 12:29:55 +01:00
parent 6771e8d8dc
commit c95559e554
4 changed files with 2 additions and 63 deletions

View File

@ -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(

View File

@ -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.

View File

@ -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)

View File

@ -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