diff --git a/data/xkb_keycodes_template b/data/xkb_keycodes_template index 4b19c5de..bc783a16 100644 --- a/data/xkb_keycodes_template +++ b/data/xkb_keycodes_template @@ -3,6 +3,5 @@ default xkb_keycodes "basic" {{ minimum = {minimum}; maximum = {maximum}; - include "evdev" {xkb_keycodes} }}; diff --git a/data/xkb_symbols_template b/data/xkb_symbols_template index 41066f74..b5fcc86d 100644 --- a/data/xkb_symbols_template +++ b/data/xkb_symbols_template @@ -4,7 +4,6 @@ // /usr/share/X11/xkb/keycodes/key-mapper default xkb_symbols "basic" {{ - include "{system_default}" name[Group1] = "{name}"; {xkb_symbols} }}; diff --git a/keymapper/X.py b/keymapper/X.py index 43b7b45c..feb6d06d 100644 --- a/keymapper/X.py +++ b/keymapper/X.py @@ -102,7 +102,6 @@ def create_setxkbmap_config(device, preset): device : string preset : string """ - print('create_setxkbmap_config', len(mapping), mapping._mapping) if len(mapping) == 0: logger.debug('Got empty mappings') return None @@ -175,9 +174,7 @@ def create_identity_mapping(): # and the minimum 8 maximum = 255 minimum = 8 - for keycode, _ in mapping: - # only those keys that are in the mapping, so that the others - # get mappings from the default keyboard. + for keycode in range(minimum, maximum + 1): xkb_keycodes.append(f'<{keycode}> = {keycode};') template_path = get_data_path('xkb_keycodes_template') @@ -191,7 +188,7 @@ def create_identity_mapping(): ) if not os.path.exists(KEYCODES_PATH): - logger.info('Creating "%s"', KEYCODES_PATH) + logger.debug('Creating "%s"', KEYCODES_PATH) os.makedirs(os.path.dirname(KEYCODES_PATH), exist_ok=True) os.mknod(KEYCODES_PATH) with open(KEYCODES_PATH, 'w') as keycodes: @@ -208,8 +205,6 @@ def generate_symbols_content(device, preset): device : string preset : string """ - system_default = 'us' # TODO get the system default - if len(mapping) == 0: raise ValueError('Mapping is empty') @@ -224,7 +219,7 @@ def generate_symbols_content(device, preset): for keycode, character in mapping: if f'<{keycode}>' not in keycodes: logger.error(f'Unknown keycode <{keycode}> for "{character}"') - # continue, otherwise X would crash when loading + # don't append that one, otherwise X would crash when loading continue xkb_symbols.append(f'key <{keycode}> {{ [ {character} ] }};') if len(xkb_symbols) == 0: @@ -237,8 +232,7 @@ def generate_symbols_content(device, preset): result = template.format( name=f'{device}/{preset}', - xkb_symbols='\n '.join(xkb_symbols), - system_default=system_default + xkb_symbols='\n '.join(xkb_symbols) ) return result @@ -259,4 +253,28 @@ def get_xinput_id_mapping(): names = [name for name in names if name != ''] ids = [int(id) for id in ids if id != ''] - return zip(names, ids) \ No newline at end of file + return zip(names, ids) + + +def parse_symbols_file(device, preset): + """Parse a symbols file and return the keycodes.""" + path = get_home_path(device, preset) + + if not os.path.exists(path): + logger.debug( + 'Tried to load non existing preset "%s" for %s', + preset, device + ) + mapping.empty() + mapping.changed = False + return + + with open(path, 'r') as f: + # from "key <12> { [ 1 ] };" extract 12 and 1, + # avoid lines that start with special characters + # (might be comments) + result = re.findall(r'\n\s+?key <(.+?)>.+?\[\s+(\w+)', f.read()) + logger.debug('Found %d mappings in this preset', len(result)) + for keycode, character in result: + mapping.changed = False + mapping.change(None, int(keycode), character) diff --git a/keymapper/gtk/window.py b/keymapper/gtk/window.py index f97907ff..16a5da87 100755 --- a/keymapper/gtk/window.py +++ b/keymapper/gtk/window.py @@ -29,7 +29,7 @@ from gi.repository import Gtk, Gdk, GLib from keymapper.data import get_data_path from keymapper.X import create_setxkbmap_config, apply_preset, \ - create_preset, mapping + create_preset, mapping, parse_symbols_file from keymapper.presets import get_presets, find_newest_preset, \ delete_preset, rename_preset from keymapper.logger import logger @@ -141,6 +141,7 @@ class Window: """Remove all rows from the mappings table.""" key_list = self.get('key_list') key_list.forall(key_list.remove) + mapping.empty() def on_save_preset_clicked(self, button): """Save changes to a preset to the file system.""" @@ -215,10 +216,7 @@ class Window: logger.debug('Selecting preset "%s"', preset) self.selected_preset = preset - mapping.load( - self.selected_device, - self.selected_preset - ) + parse_symbols_file(self.selected_device, self.selected_preset) key_list = self.get('key_list') for keycode, character in mapping: diff --git a/keymapper/mapping.py b/keymapper/mapping.py index 35f968f3..fa05ccc6 100644 --- a/keymapper/mapping.py +++ b/keymapper/mapping.py @@ -19,13 +19,9 @@ # along with key-mapper. If not, see . -"""TODO""" +"""Contains and manages mappings.""" -import os -import re - -from keymapper.paths import get_home_path from keymapper.logger import logger @@ -46,34 +42,6 @@ class Mapping: def __len__(self): return len(self._mapping) - def load(self, device, preset): - """Parse the X config to replace the current mapping with that one.""" - # TODO put that logic out of the mapper to make mapper display server - # agnostic - path = get_home_path(device, preset) - - if not os.path.exists(path): - logger.debug( - 'Tried to load non existing preset "%s" for %s', - preset, device - ) - self._mapping = {} - return - - with open(path, 'r') as f: - # from "key <12> { [ 1 ] };" extract 12 and 1, - # avoid lines that start with special characters - # (might be comments) - result = re.findall(r'\n\s+?key <(.+?)>.+?\[\s+(\w+)', f.read()) - logger.debug('Found %d mappings in this preset', len(result)) - self._mapping = { - int(keycode): character - for keycode, character - in result - } - - self.changed = False - def change(self, previous_keycode, new_keycode, character): """Replace the mapping of a keycode with a different one. diff --git a/keymapper/x11/__init__.py b/keymapper/x11/__init__.py deleted file mode 100644 index 8d26ae46..00000000 --- a/keymapper/x11/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/python3 -# -*- coding: utf-8 -*- -# key-mapper - GUI for device specific keyboard mappings -# Copyright (C) 2020 sezanzeb -# -# This file is part of key-mapper. -# -# key-mapper is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# key-mapper is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with key-mapper. If not, see . diff --git a/tests/testcases/config.py b/tests/testcases/config.py index a1f905d7..39ff6eac 100644 --- a/tests/testcases/config.py +++ b/tests/testcases/config.py @@ -75,11 +75,8 @@ class TestConfig(unittest.TestCase): self.assertTrue(os.path.exists(KEYCODES_PATH)) with open(KEYCODES_PATH, 'r') as f: keycodes = f.read() - self.assertNotIn('<9> = 9;', keycodes) - self.assertIn('<10> = 10;', keycodes) - self.assertIn('<11> = 11;', keycodes) - self.assertIn('<12> = 12;', keycodes) - self.assertNotIn('<13> = 13;', keycodes) + self.assertIn('<8> = 8;', keycodes) + self.assertIn('<255> = 255;', keycodes) content = generate_symbols_content('device', 'preset') self.assertIn('key <10> { [ a ] };', content)