threw some TODOs into it, started on the daemon executable

This commit is contained in:
sezanzeb 2020-11-20 01:50:40 +01:00 committed by sezanzeb
parent aa9df32e2b
commit e987f2654e
5 changed files with 170 additions and 9 deletions

View File

@ -52,8 +52,8 @@ if __name__ == '__main__':
window = Window()
def stop_injecting():
if window.keycode_reader is not None:
window.keycode_reader.stop_injecting()
if window.keycode_injector is not None:
window.keycode_injector.stop_injecting()
atexit.register(stop_injecting)

71
bin/key-mapper-service Normal file
View File

@ -0,0 +1,71 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# key-mapper - GUI for device specific keyboard mappings
# Copyright (C) 2020 sezanzeb <proxima@hip70890b.de>
#
# 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 <https://www.gnu.org/licenses/>.
"""Starts injecting keycodes based on the configuration."""
import sys
import atexit
import getpass
from argparse import ArgumentParser
from keymapper.logger import logger, update_verbosity, log_info
from keymapper.config import iterate_autoload_presets
from keymapper.injector import KeycodeInjector
from keymapper.mapping import Mapping
injectors = {}
def stop():
"""Properly stop the daemon."""
for injector in injectors:
injector.stop_injecting()
if __name__ == '__main__':
parser = ArgumentParser()
parser.add_argument(
'-d', '--debug', action='store_true', dest='debug',
help='Displays additional debug information',
default=False
)
options = parser.parse_args(sys.argv[1:])
update_verbosity(options.debug)
log_info()
atexit.register(stop)
if getpass.getuser() != 'root' and 'unittest' not in sys.modules.keys():
logger.warn('Without sudo, your devices may not be visible')
for device, preset in iterate_autoload_presets():
mapping = Mapping()
mapping.load(device, preset)
# TODO keycode injector needs a mapping param,
# TODO the single custom_mapping only for the UI, because the
# service has multiple
injectors[device] = KeycodeInjector(device, mapping)
# TODO Dbus server wait for the UI to request applying a different preset
# or disabling the injection for a specific device.

89
keymapper/config.py Normal file
View File

@ -0,0 +1,89 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# key-mapper - GUI for device specific keyboard mappings
# Copyright (C) 2020 sezanzeb <proxima@hip70890b.de>
#
# 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 <https://www.gnu.org/licenses/>.
"""Store which presets should be enabled for which device on login."""
import os
import json
from keymapper.paths import CONFIG
from keymapper.logger import logger
CONFIG_PATH = os.path.join(CONFIG, 'config')
# an empty config with basic expected substructures
INITIAL_CONFIG = {
'autoload': [],
'map_EV_REL_devices': True
}
_config = INITIAL_CONFIG.copy()
def set_autoload_preset(device, preset):
"""Set a preset to be automatically applied on start."""
_config['autoload'].append({
'device': device,
'preset': preset
})
def iterate_autoload_presets():
"""Yield tuples of (device, preset)."""
for entry in _config['autoload']:
yield entry['device'], entry['preset']
def set_modify_movement_devices(active):
"""Set if devices that control movements should also be mapped.
This causes many movements event to be passed through python code,
and if this ever seems to affect the responsiveness of mouse movements,
it can be disabled. This may make mapping some keys of the device
impossible.
"""
global _config
_config['map_EV_REL_devices'] = active
def load_config():
"""Load the config from the file system."""
global _config
if not os.path.exists(CONFIG_PATH):
# has not yet been saved
logger.debug('Config file not found')
_config = INITIAL_CONFIG.copy()
return
with open(CONFIG_PATH, 'r') as f:
_config = INITIAL_CONFIG.copy()
_config.update(json.load(f))
logger.info('Loaded config from %s', CONFIG_PATH)
def save_config():
"""Save the config to the file system."""
with open(CONFIG_PATH, 'w') as f:
json.dump(_config, f)
logger.info('Saved config to %s', CONFIG_PATH)

View File

@ -75,7 +75,7 @@ class Window:
def __init__(self):
self.selected_device = None
self.selected_preset = None
self.keycode_reader = None
self.keycode_injector = None
css_provider = Gtk.CssProvider()
with open(get_data_path('style.css'), 'r') as f:
@ -201,8 +201,8 @@ class Window:
def on_apply_system_layout_clicked(self, button):
"""Load the mapping."""
if self.keycode_reader is not None:
self.keycode_reader.stop_injecting()
if self.keycode_injector is not None:
self.keycode_injector.stop_injecting()
self.get('status_bar').push(
CTX_APPLY,
f'Applied the system default'
@ -250,10 +250,12 @@ class Window:
CTX_APPLY,
f'Applied "{self.selected_preset}"'
)
if self.keycode_reader is not None:
self.keycode_reader.stop_injecting()
# TODO write dbus.py and call apply_preset on that one instead
# which sends a message to key-mapper-service
if self.keycode_injector is not None:
self.keycode_injector.stop_injecting()
try:
self.keycode_reader = KeycodeInjector(self.selected_device)
self.keycode_injector = KeycodeInjector(self.selected_device)
except OSError:
self.get('status_bar').push(
CTX_ERROR,

View File

@ -104,7 +104,6 @@ def _start_injecting_worker(path, pipe):
device = _grab(path)
if device is None:
print('lakjdsflakdsjfa')
pipe.send(FAILED)
return