diff --git a/README.md b/README.md index 9dae6ec2..07d3acc5 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,5 @@ work. - [ ] load xmodmap files from the config path - [x] show a list that can be extended with a `[+]` button - [ ] The list shows `[keycode, current key for that keycode -> target]` -- [ ] generate a xmodmap.*.whatever file out of that (like for example https://github.com/sezanzeb/colemakDE/blob/master/xmodmap.colemak.de) -- [ ] load that file (`setxkbmap funnystuff; xmodmap xmodmap.asdf.whatever`, `setxkbmap funnystuff -device `). -- [ ] Does it need to be loaded on every startup or every time the device connects? If so, add udev rules +- [ ] generate a file for /usr/share/X11/xkb/symbols/ for each preset, (symlink to home .config/?) +- [ ] load that file with `setxkbmap preset1234 -device 13` (on startup?, udev on mouse connect?) diff --git a/bin/key-mapper-gtk b/bin/key-mapper-gtk index e69ef84e..3b241292 100755 --- a/bin/key-mapper-gtk +++ b/bin/key-mapper-gtk @@ -32,7 +32,8 @@ gi.require_version('GLib', '2.0') from gi.repository import Gtk from keymapper.data import get_data_path -from keymapper.presets import find_devices, get_presets, get_mappings, \ +from keymapper.X import find_devices +from keymapper.presets import get_presets, get_mappings, \ find_newest_preset, create_preset from keymapper.logger import logger, update_verbosity, log_info @@ -129,7 +130,7 @@ class Window: def on_select_device(self, device): """List all presets, create one if none exist yet.""" if isinstance(device, Gtk.ComboBoxText): - preset = device.get_active_text() + device = device.get_active_text() device = device.get_active_text() presets = get_presets(device) diff --git a/keymapper/X.py b/keymapper/X.py new file mode 100644 index 00000000..afbf71e2 --- /dev/null +++ b/keymapper/X.py @@ -0,0 +1,71 @@ +#!/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 . + + +"""Stuff that interacts with the X Server""" + + +import re +import subprocess + + +# mapping of keycode to character, e.g. 38 to the 'A' key of the keyboard. +# This depends on the configured keyboard layout. +# example: 38: "a A a A ae AE ae" +key_mapping = {} + + +def load_keymapping(): + """Load the current active mapping of keycodes""" + # to get ASCII codes: xmodmap -pk + output = subprocess.check_output(['xmodmap', '-p']).decode() + for line in output.split('\n'): + search = re.search(r'(\d+) = (.+)', line) + if search is not None: + key_mapping[search[0]] = search[1] + + +def get_xinput_list(type): + """Run xinput and get the result as list. + + Parameters + ---------- + type : string + Ine of 'id' or 'name' + """ + output = subprocess.check_output(['xinput', 'list', f'--{type}-only']) + return [line for line in output.decode().split('\n') if line != ''] + + +def find_devices(): + """Get a list of (id, name) for each input device.""" + # `xinput list` + ids = get_xinput_list('id') + names = get_xinput_list('name') + + # names contains duplicates and "Virtual"-somethings, filter those + known_names = [] + # TODO remember all IDS? try each one of them for setxkbmap until success? + result = [] + for (id, name) in zip(ids, names): + if name not in known_names and not name.startswith('Virtual'): + known_names.append(name) + result.append((id, name)) + return result diff --git a/keymapper/presets.py b/keymapper/presets.py index d205da7a..2ba79ee6 100644 --- a/keymapper/presets.py +++ b/keymapper/presets.py @@ -41,22 +41,6 @@ def get_xinput_list(type): return [line for line in output.decode().split('\n') if line != ''] -def find_devices(): - """Get a list of (id, name) for each input device.""" - # `xinput list` - ids = get_xinput_list('id') - names = get_xinput_list('name') - - # names contains duplicates and "Virtual"-somethings, filter those - known_names = [] - result = [] - for (id, name) in zip(ids, names): - if name not in known_names and not name.startswith('Virtual'): - known_names.append(name) - result.append((id, name)) - return result - - def get_presets(device): """Get all configured presets for the device, sorted by modification date.