rules: better determination of keycodes and handle keysym level

This commit is contained in:
Peter F. Patel-Schneider 2022-05-04 11:37:05 -04:00
parent 2b4e272331
commit 97344c4660
2 changed files with 34 additions and 15 deletions

View File

@ -155,14 +155,21 @@ For settings that use gestures as an argument the internal name of the gesture i
which can be found in the GESTURE2_GESTURES_LABELS structure in lib/logitech_receiver/settings_templates.
For boolean settings '~' can be used to toggle the setting.
A `KeyPress` action takes a sequence of X11 key symbols and simulates a chorded keypress on the keyboard,
such as "A", "Shift+A", or "Control+A".
Use separate `KeyPress` actions for multiple characters.
If Solaar can determine the current modifier keys,
any key symbols that correspond to these modifier keys are not pressed.
A `KeyPress` action takes a sequence of X11 key symbols, such as "a" or "Control+a",
and simulates a chorded keypress on the keyboard to produce these symbols.
Use separate `KeyPress` actions for multiple characters,
i.e., don't use a single `KeyPress` like 'a+b'.
If a key symbol can only be produced by a shfited or level 3 keypress, e.g., "A",
then Solaar will add keypresses to produce that keysymbol,
e.g., simulating a left shift keypress to get "A" instead of "a".
If Solaar can determine the current key modifiers (shift, control, etc.)
any key symbols that correspond to these modifier keys are not pressed,
so if the shift key is currently down on a keyboard Solaar will not bother to simulate a shift key.
Simulating input in Linux is complex.
Solaar has to try to determine which keyboard key corresponds to which input character as it cannot directly
simulate inputting a character and, unfortunately, this determination can go wrong in multiple ways and is more likely
simulate inputting a key symbol.
Unfortunately, this determination can go wrong in several ways and is more likely
to go wrong under Wayland than under X11.
A `MouseScroll` action takes a sequence of two numbers and simulates a horizontal and vertical mouse scroll of these amounts.

View File

@ -836,14 +836,14 @@ class KeyPress(Action):
def keysym_to_keycode(self, keysym, modifiers): # maybe should take shift into account
group = kbdgroup() or 0
keycodes = gkeymap.get_entries_for_keyval(keysym)
if len(keycodes.keys) == 1:
k = keycodes.keys[0]
return k.keycode
else:
(keycode, level) = (None, None)
for k in keycodes.keys:
if group is None or group == k.group:
return k.keycode
if (group == k.group or len(keycodes.keys) == 1) and k.keycode < 256 and (level is None or k.level < level):
keycode = k.keycode
level = k.level
if keycode is None:
_log.warn('rule KeyPress key symbol not currently available %s', self)
return (keycode, level)
def __str__(self):
return 'KeyPress: ' + ' '.join(self.key_names)
@ -852,17 +852,29 @@ class KeyPress(Action):
code = modifier_code(k)
return not (code is not None and modifiers & (1 << code))
def mods(self, level, modifiers, direction):
if level == 2 or level == 3:
(sk, _) = self.keysym_to_keycode(XK_KEYS.get('ISO_Level3_Shift', None), modifiers)
if sk and self.needed(sk, modifiers):
simulate_key(sk, direction)
if level == 1 or level == 3:
(sk, _) = self.keysym_to_keycode(XK_KEYS.get('Shift_L', None), modifiers)
if sk and self.needed(sk, modifiers):
simulate_key(sk, direction)
def keyDown(self, keysyms, modifiers):
for k in keysyms:
keycode = self.keysym_to_keycode(k, modifiers)
(keycode, level) = self.keysym_to_keycode(k, modifiers)
if keycode and self.needed(keycode, modifiers):
self.mods(level, modifiers, _KEY_PRESS)
simulate_key(keycode, _KEY_PRESS)
def keyUp(self, keysyms, modifiers):
for k in keysyms:
keycode = self.keysym_to_keycode(k, modifiers)
(keycode, level) = self.keysym_to_keycode(k, modifiers)
if keycode and self.needed(keycode, modifiers):
simulate_key(keycode, _KEY_RELEASE)
self.mods(level, modifiers, _KEY_RELEASE)
def evaluate(self, feature, notification, device, status, last_result):
if gkeymap: