diversion: Simplify and type hint
- Make static method an easy testable function. - Fix variable name clashes
This commit is contained in:
parent
3ffa4e30f1
commit
1d5b61fbf2
|
@ -26,11 +26,15 @@ import subprocess
|
||||||
import sys as _sys
|
import sys as _sys
|
||||||
import time as _time
|
import time as _time
|
||||||
|
|
||||||
|
from typing import Dict
|
||||||
|
from typing import Tuple
|
||||||
|
|
||||||
import dbus
|
import dbus
|
||||||
import gi
|
import gi
|
||||||
import keysyms.keysymdef as _keysymdef
|
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
|
from keysyms import keysymdef
|
||||||
|
|
||||||
# There is no evdev on macOS or Windows. Diversion will not work without
|
# There is no evdev on macOS or Windows. Diversion will not work without
|
||||||
# it but other Solaar functionality is available.
|
# it but other Solaar functionality is available.
|
||||||
if _platform.system() in ("Darwin", "Windows"):
|
if _platform.system() in ("Darwin", "Windows"):
|
||||||
|
@ -84,7 +88,7 @@ logger = logging.getLogger(__name__)
|
||||||
# Xtest extension to X11 - provides input simulation, partly works under Wayland
|
# Xtest extension to X11 - provides input simulation, partly works under Wayland
|
||||||
# Wayland - provides input simulation
|
# Wayland - provides input simulation
|
||||||
|
|
||||||
XK_KEYS = _keysymdef.keysymdef
|
XK_KEYS: Dict[str, int] = keysymdef.keysymdef
|
||||||
|
|
||||||
# Event codes - can't use Xlib.X codes because Xlib might not be available
|
# Event codes - can't use Xlib.X codes because Xlib might not be available
|
||||||
_KEY_RELEASE = 0
|
_KEY_RELEASE = 0
|
||||||
|
@ -113,12 +117,24 @@ try:
|
||||||
except Exception:
|
except Exception:
|
||||||
_x11 = False # X11 is not available
|
_x11 = False # X11 is not available
|
||||||
|
|
||||||
|
# Globals
|
||||||
xtest_available = True # Xtest might be available
|
xtest_available = True # Xtest might be available
|
||||||
xdisplay = None
|
xdisplay = None
|
||||||
Xkbdisplay = None # xkb might be available
|
Xkbdisplay = None # xkb might be available
|
||||||
modifier_keycodes = []
|
modifier_keycodes = []
|
||||||
XkbUseCoreKbd = 0x100
|
XkbUseCoreKbd = 0x100
|
||||||
|
|
||||||
|
udevice = None
|
||||||
|
|
||||||
|
key_down = None
|
||||||
|
key_up = None
|
||||||
|
|
||||||
|
keys_down = []
|
||||||
|
g_keys_down = 0
|
||||||
|
m_keys_down = 0
|
||||||
|
mr_key_down = False
|
||||||
|
thumb_wheel_displacement = 0
|
||||||
|
|
||||||
_dbus_interface = None
|
_dbus_interface = None
|
||||||
|
|
||||||
|
|
||||||
|
@ -224,8 +240,6 @@ else:
|
||||||
key_events = []
|
key_events = []
|
||||||
devicecap = {}
|
devicecap = {}
|
||||||
|
|
||||||
udevice = None
|
|
||||||
|
|
||||||
|
|
||||||
def setup_uinput():
|
def setup_uinput():
|
||||||
global udevice
|
global udevice
|
||||||
|
@ -261,12 +275,8 @@ def modifier_code(keycode):
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
|
||||||
key_down = None
|
def signed(bytes_: bytes) -> int:
|
||||||
key_up = None
|
return int.from_bytes(bytes_, "big", signed=True)
|
||||||
|
|
||||||
|
|
||||||
def signed(bytes):
|
|
||||||
return int.from_bytes(bytes, "big", signed=True)
|
|
||||||
|
|
||||||
|
|
||||||
def xy_direction(_x, _y):
|
def xy_direction(_x, _y):
|
||||||
|
@ -432,7 +442,7 @@ def thumb_wheel_down(f, r, d, a):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def charging(f, r, d, a):
|
def charging(f, r, d, _a):
|
||||||
if (
|
if (
|
||||||
(f == _F.BATTERY_STATUS and r == 0 and 1 <= d[2] <= 4)
|
(f == _F.BATTERY_STATUS and r == 0 and 1 <= d[2] <= 4)
|
||||||
or (f == _F.BATTERY_VOLTAGE and r == 0 and d[2] & (1 << 7))
|
or (f == _F.BATTERY_VOLTAGE and r == 0 and d[2] & (1 << 7))
|
||||||
|
@ -909,7 +919,7 @@ def bit_test(start, end, bits):
|
||||||
|
|
||||||
|
|
||||||
def range_test(start, end, min, max):
|
def range_test(start, end, min, max):
|
||||||
def range_test_helper(f, r, d):
|
def range_test_helper(_f, _r, d):
|
||||||
value = int.from_bytes(d[start:end], byteorder="big", signed=True)
|
value = int.from_bytes(d[start:end], byteorder="big", signed=True)
|
||||||
return min <= value <= max and (value if value else True)
|
return min <= value <= max and (value if value else True)
|
||||||
|
|
||||||
|
@ -965,10 +975,8 @@ class TestBytes(Condition):
|
||||||
isinstance(test, list)
|
isinstance(test, list)
|
||||||
and 2 < len(test) <= 4
|
and 2 < len(test) <= 4
|
||||||
and all(isinstance(t, int) for t in test)
|
and all(isinstance(t, int) for t in test)
|
||||||
and test[0] >= 0
|
and 0 <= test[0] <= 16
|
||||||
and test[0] <= 16
|
and 0 <= test[1] <= 16
|
||||||
and test[1] >= 0
|
|
||||||
and test[1] <= 16
|
|
||||||
and test[0] < test[1]
|
and test[0] < test[1]
|
||||||
):
|
):
|
||||||
self.function = bit_test(*test) if len(test) == 3 else range_test(*test)
|
self.function = bit_test(*test) if len(test) == 3 else range_test(*test)
|
||||||
|
@ -1113,6 +1121,32 @@ class Action(RuleComponent):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def keysym_to_keycode(keysym, _modifiers) -> Tuple[int, int]: # maybe should take shift into account
|
||||||
|
"""Reverse the keycode to keysym mapping.
|
||||||
|
|
||||||
|
Warning:
|
||||||
|
This is an attempt to reverse the keycode to keysym mappping in XKB.
|
||||||
|
It may not be completely general.
|
||||||
|
"""
|
||||||
|
group = kbdgroup() or 0
|
||||||
|
keycodes = gkeymap.get_entries_for_keyval(keysym)
|
||||||
|
(keycode, level) = (None, None)
|
||||||
|
for k in keycodes.keys: # mappings that have the correct group
|
||||||
|
if group == k.group and k.keycode < 256 and (level is None or k.level < level):
|
||||||
|
keycode = k.keycode
|
||||||
|
level = k.level
|
||||||
|
if keycode or group == 0:
|
||||||
|
return keycode, level
|
||||||
|
|
||||||
|
for k in keycodes.keys: # mappings for group 0 where keycode only has group 0 mappings
|
||||||
|
if 0 == k.group and k.keycode < 256 and (level is None or k.level < level):
|
||||||
|
(a, m, vs) = gkeymap.get_entries_for_keycode(k.keycode)
|
||||||
|
if a and all(mk.group == 0 for mk in m):
|
||||||
|
keycode = k.keycode
|
||||||
|
level = k.level
|
||||||
|
return keycode, level
|
||||||
|
|
||||||
|
|
||||||
class KeyPress(Action):
|
class KeyPress(Action):
|
||||||
def __init__(self, args, warn=True):
|
def __init__(self, args, warn=True):
|
||||||
self.key_names, self.action = self.regularize_args(args)
|
self.key_names, self.action = self.regularize_args(args)
|
||||||
|
@ -1137,25 +1171,6 @@ class KeyPress(Action):
|
||||||
action = args[1]
|
action = args[1]
|
||||||
return keys, action
|
return keys, action
|
||||||
|
|
||||||
# WARNING: This is an attempt to reverse the keycode to keysym mappping in XKB. It may not be completely general.
|
|
||||||
def keysym_to_keycode(self, keysym, modifiers): # maybe should take shift into account
|
|
||||||
group = kbdgroup() or 0
|
|
||||||
keycodes = gkeymap.get_entries_for_keyval(keysym)
|
|
||||||
(keycode, level) = (None, None)
|
|
||||||
for k in keycodes.keys: # mappings that have the correct group
|
|
||||||
if group == k.group and k.keycode < 256 and (level is None or k.level < level):
|
|
||||||
keycode = k.keycode
|
|
||||||
level = k.level
|
|
||||||
if keycode or group == 0:
|
|
||||||
return (keycode, level)
|
|
||||||
for k in keycodes.keys: # mappings for group 0 where keycode only has group 0 mappings
|
|
||||||
if 0 == k.group and k.keycode < 256 and (level is None or k.level < level):
|
|
||||||
(a, m, vs) = gkeymap.get_entries_for_keycode(k.keycode)
|
|
||||||
if a and all(mk.group == 0 for mk in m):
|
|
||||||
keycode = k.keycode
|
|
||||||
level = k.level
|
|
||||||
return (keycode, level)
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "KeyPress: " + " ".join(self.key_names) + " " + self.action
|
return "KeyPress: " + " ".join(self.key_names) + " " + self.action
|
||||||
|
|
||||||
|
@ -1165,26 +1180,26 @@ class KeyPress(Action):
|
||||||
|
|
||||||
def mods(self, level, modifiers, direction):
|
def mods(self, level, modifiers, direction):
|
||||||
if level == 2 or level == 3:
|
if level == 2 or level == 3:
|
||||||
(sk, _) = self.keysym_to_keycode(XK_KEYS.get("ISO_Level3_Shift", None), modifiers)
|
(sk, _) = keysym_to_keycode(XK_KEYS.get("ISO_Level3_Shift", None), modifiers)
|
||||||
if sk and self.needed(sk, modifiers):
|
if sk and self.needed(sk, modifiers):
|
||||||
simulate_key(sk, direction)
|
simulate_key(sk, direction)
|
||||||
if level == 1 or level == 3:
|
if level == 1 or level == 3:
|
||||||
(sk, _) = self.keysym_to_keycode(XK_KEYS.get("Shift_L", None), modifiers)
|
(sk, _) = keysym_to_keycode(XK_KEYS.get("Shift_L", None), modifiers)
|
||||||
if sk and self.needed(sk, modifiers):
|
if sk and self.needed(sk, modifiers):
|
||||||
simulate_key(sk, direction)
|
simulate_key(sk, direction)
|
||||||
|
|
||||||
def keyDown(self, keysyms, modifiers):
|
def keyDown(self, keysyms_, modifiers):
|
||||||
for k in keysyms:
|
for k in keysyms_:
|
||||||
(keycode, level) = self.keysym_to_keycode(k, modifiers)
|
(keycode, level) = keysym_to_keycode(k, modifiers)
|
||||||
if keycode is None:
|
if keycode is None:
|
||||||
logger.warning("rule KeyPress key symbol not currently available %s", self)
|
logger.warning("rule KeyPress key symbol not currently available %s", self)
|
||||||
elif self.action != CLICK or self.needed(keycode, modifiers): # only check needed when clicking
|
elif self.action != CLICK or self.needed(keycode, modifiers): # only check needed when clicking
|
||||||
self.mods(level, modifiers, _KEY_PRESS)
|
self.mods(level, modifiers, _KEY_PRESS)
|
||||||
simulate_key(keycode, _KEY_PRESS)
|
simulate_key(keycode, _KEY_PRESS)
|
||||||
|
|
||||||
def keyUp(self, keysyms, modifiers):
|
def keyUp(self, keysyms_, modifiers):
|
||||||
for k in keysyms:
|
for k in keysyms_:
|
||||||
(keycode, level) = self.keysym_to_keycode(k, modifiers)
|
(keycode, level) = keysym_to_keycode(k, modifiers)
|
||||||
if keycode and (self.action != CLICK or self.needed(keycode, modifiers)): # only check needed when clicking
|
if keycode and (self.action != CLICK or self.needed(keycode, modifiers)): # only check needed when clicking
|
||||||
simulate_key(keycode, _KEY_RELEASE)
|
simulate_key(keycode, _KEY_RELEASE)
|
||||||
self.mods(level, modifiers, _KEY_RELEASE)
|
self.mods(level, modifiers, _KEY_RELEASE)
|
||||||
|
@ -1420,12 +1435,6 @@ if True:
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
keys_down = []
|
|
||||||
g_keys_down = 0
|
|
||||||
m_keys_down = 0
|
|
||||||
mr_key_down = False
|
|
||||||
thumb_wheel_displacement = 0
|
|
||||||
|
|
||||||
|
|
||||||
def key_is_down(key):
|
def key_is_down(key):
|
||||||
if key == _CONTROL.MR:
|
if key == _CONTROL.MR:
|
||||||
|
|
Loading…
Reference in New Issue