xkb
sezanzeb 4 years ago committed by sezanzeb
parent 07c2d86c26
commit ffcf9c6b1d

@ -84,11 +84,11 @@ class _Config:
path : string path : string
For example 'macros.keystroke_sleep_ms' For example 'macros.keystroke_sleep_ms'
""" """
def do(parent, child, chunk): def callback(parent, child, chunk):
if child is not None: if child is not None:
del parent[chunk] del parent[chunk]
self._resolve(path, do) self._resolve(path, callback)
def set(self, path, value): def set(self, path, value):
"""Set a config key. """Set a config key.
@ -99,10 +99,10 @@ class _Config:
For example 'macros.keystroke_sleep_ms' For example 'macros.keystroke_sleep_ms'
value : any value : any
""" """
def do(parent, child, chunk): def callback(parent, child, chunk):
parent[chunk] = value parent[chunk] = value
self._resolve(path, do) self._resolve(path, callback)
def get(self, path, log_unknown=True): def get(self, path, log_unknown=True):
"""Get a config value. If not set, return the default """Get a config value. If not set, return the default
@ -114,12 +114,12 @@ class _Config:
log_unknown : bool log_unknown : bool
If True, write an error. If True, write an error.
""" """
def do(parent, child, chunk): def callback(parent, child, chunk):
return child return child
resolved = self._resolve(path, do) resolved = self._resolve(path, callback)
if resolved is None: if resolved is None:
resolved = self._resolve(path, do, INITIAL_CONFIG) resolved = self._resolve(path, callback, INITIAL_CONFIG)
if resolved is None and log_unknown: if resolved is None and log_unknown:
logger.error('Unknown config key "%s"', path) logger.error('Unknown config key "%s"', path)

@ -26,7 +26,6 @@ https://github.com/LEW21/pydbus/tree/cc407c8b1d25b7e28a6d661a29f9e661b1c9b964/ex
import subprocess import subprocess
import sys
from pydbus import SessionBus from pydbus import SessionBus

@ -40,6 +40,8 @@ def get_data_path(filename=''):
distros this is somewhat complicated. Ubuntu wants to use /usr/local distros this is somewhat complicated. Ubuntu wants to use /usr/local
for data_files, but not everything can be placed there. for data_files, but not everything can be placed there.
""" """
global logged
source_path = None source_path = None
try: try:
source_path = pkg_resources.require('key-mapper')[0].location source_path = pkg_resources.require('key-mapper')[0].location
@ -51,8 +53,6 @@ def get_data_path(filename=''):
# prefix path for data # prefix path for data
# https://docs.python.org/3/distutils/setupscript.html?highlight=package_data#installing-additional-files # noqa pylint: disable=line-too-long # https://docs.python.org/3/distutils/setupscript.html?highlight=package_data#installing-additional-files # noqa pylint: disable=line-too-long
global logged
data_path = None data_path = None
# python3.8/dist-packages python3.7/site-packages, /usr/share, # python3.8/dist-packages python3.7/site-packages, /usr/share,
# /usr/local/share, endless options # /usr/local/share, endless options

@ -23,7 +23,6 @@
import re import re
import os
import asyncio import asyncio
import time import time
import subprocess import subprocess
@ -114,7 +113,7 @@ class KeycodeInjector:
def _map_codes_to_codes(self): def _map_codes_to_codes(self):
"""To quickly get target keycodes during operation.""" """To quickly get target keycodes during operation."""
_code_to_code = {} _code_to_code = {}
for (ev_type, keycode), output in self.mapping: for (_, keycode), output in self.mapping:
if is_this_a_macro(output): if is_this_a_macro(output):
continue continue
@ -297,7 +296,7 @@ class KeycodeInjector:
# each device parses the macros with a different handler # each device parses the macros with a different handler
logger.debug('Parsing macros for %s', path) logger.debug('Parsing macros for %s', path)
macros = {} macros = {}
for (ev_type, keycode), output in self.mapping: for (_, keycode), output in self.mapping:
if is_this_a_macro(output): if is_this_a_macro(output):
macro = parse(output) macro = parse(output)
if macro is None: if macro is None:

@ -30,7 +30,7 @@ from keymapper.logger import logger
from keymapper.dev.ev_abs_mapper import JOYSTICK from keymapper.dev.ev_abs_mapper import JOYSTICK
def should_map_event_as_btn(type, code): def should_map_event_as_btn(ev_type, code):
"""Does this event describe a button. """Does this event describe a button.
Especially important for gamepad events, some of the buttons Especially important for gamepad events, some of the buttons
@ -38,15 +38,15 @@ def should_map_event_as_btn(type, code):
Parameters Parameters
---------- ----------
type : int ev_type : int
one of evdev.events one of evdev.events
code : int code : int
linux keycode linux keycode
""" """
if type == evdev.events.EV_KEY: if ev_type == evdev.events.EV_KEY:
return True return True
if type == evdev.events.EV_ABS and code not in JOYSTICK: if ev_type == evdev.events.EV_ABS and code not in JOYSTICK:
return True return True
return False return False

@ -53,8 +53,7 @@ DEBUG = 6
def is_this_a_macro(output): def is_this_a_macro(output):
"""Figure out if this is a macro.""" """Figure out if this is a macro."""
if '(' in output and ')' in output and len(output) >= 4: return '(' in output and ')' in output and len(output) >= 4
return True
class _Macro: class _Macro:

@ -33,8 +33,8 @@ from keymapper.paths import USER
def can_read_devices(): def can_read_devices():
"""If the people ever looks into the console, make sure to help them.""" """If the people ever looks into the console, make sure to help them."""
is_root = getpass.getuser() == 'root' is_root = getpass.getuser() == 'root'
is_in_input_group = USER in grp.getgrnam('input').gr_mem is_input = USER in grp.getgrnam('input').gr_mem
is_in_plugdev_group = USER in grp.getgrnam('plugdev').gr_mem is_plugdev = USER in grp.getgrnam('plugdev').gr_mem
# ubuntu. funnily, individual devices in /dev/input/ have write permitted. # ubuntu. funnily, individual devices in /dev/input/ have write permitted.
can_write = os.access('/dev/uinput', os.W_OK) can_write = os.access('/dev/uinput', os.W_OK)
@ -50,9 +50,9 @@ def can_read_devices():
) )
if not is_root: if not is_root:
if not is_in_plugdev_group: if not is_plugdev:
warn('plugdev') warn('plugdev')
if not is_in_input_group: if not is_input:
warn('input') warn('input')
if not can_write: if not can_write:
logger.error( logger.error(
@ -62,6 +62,6 @@ def can_read_devices():
{USER} {USER}
) )
ok = (is_root or (is_in_input_group and is_in_plugdev_group)) and can_write permitted = (is_root or (is_input and is_plugdev)) and can_write
return ok, is_root, is_in_input_group, is_in_plugdev_group, can_write return permitted, is_root, is_input, is_plugdev, can_write

@ -53,6 +53,7 @@ class _KeycodeReader:
self.stop_reading() self.stop_reading()
def stop_reading(self): def stop_reading(self):
"""Stop reading keycodes."""
if self._pipe is not None: if self._pipe is not None:
logger.debug('Sending close msg to reader') logger.debug('Sending close msg to reader')
self._pipe[0].send(CLOSE) self._pipe[0].send(CLOSE)

@ -23,9 +23,7 @@
import evdev import evdev
import sys
from evdev.ecodes import EV_KEY from evdev.ecodes import EV_KEY
import gi import gi
gi.require_version('Gtk', '3.0') gi.require_version('Gtk', '3.0')
gi.require_version('GLib', '2.0') gi.require_version('GLib', '2.0')
@ -114,8 +112,8 @@ class Window:
# already visible (without content) to make it look more responsive. # already visible (without content) to make it look more responsive.
gtk_iteration() gtk_iteration()
ok, _, is_input, is_plugdev, can_write = can_read_devices() permitted, _, is_input, is_plugdev, can_write = can_read_devices()
if not ok: if not permitted:
missing_groups = [] missing_groups = []
if not is_input: if not is_input:
missing_groups.append('input') missing_groups.append('input')
@ -131,7 +129,7 @@ class Window:
elif not can_write: elif not can_write:
self.get('status_bar').push( self.get('status_bar').push(
CTX_ERROR, CTX_ERROR,
f'Insufficient permissions on /dev/uinput' 'Insufficient permissions on /dev/uinput'
) )
self.populate_devices() self.populate_devices()

@ -1,23 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="73" height="20"> <svg xmlns="http://www.w3.org/2000/svg" width="80" height="20">
<linearGradient id="b" x2="0" y2="100%"> <linearGradient id="b" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/> <stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/> <stop offset="1" stop-opacity=".1"/>
</linearGradient> </linearGradient>
<mask id="anybadge_1"> <mask id="anybadge_1">
<rect width="73" height="20" rx="3" fill="#fff"/> <rect width="80" height="20" rx="3" fill="#fff"/>
</mask> </mask>
<g mask="url(#anybadge_1)"> <g mask="url(#anybadge_1)">
<path fill="#555" d="M0 0h44v20H0z"/> <path fill="#555" d="M0 0h44v20H0z"/>
<path fill="#4c1" d="M44 0h29v20H44z"/> <path fill="#4c1" d="M44 0h36v20H44z"/>
<path fill="url(#b)" d="M0 0h73v20H0z"/> <path fill="url(#b)" d="M0 0h80v20H0z"/>
</g> </g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"> <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="23.0" y="15" fill="#010101" fill-opacity=".3">pylint</text> <text x="23.0" y="15" fill="#010101" fill-opacity=".3">pylint</text>
<text x="22.0" y="14">pylint</text> <text x="22.0" y="14">pylint</text>
</g> </g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"> <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="59.5" y="15" fill="#010101" fill-opacity=".3">9.7</text> <text x="63.0" y="15" fill="#010101" fill-opacity=".3">9.76</text>
<text x="58.5" y="14">9.7</text> <text x="62.0" y="14">9.76</text>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Loading…
Cancel
Save