rules: better determination of keycodes and handle keysym level
This commit is contained in:
parent
2b4e272331
commit
97344c4660
|
@ -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.
|
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.
|
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,
|
A `KeyPress` action takes a sequence of X11 key symbols, such as "a" or "Control+a",
|
||||||
such as "A", "Shift+A", or "Control+A".
|
and simulates a chorded keypress on the keyboard to produce these symbols.
|
||||||
Use separate `KeyPress` actions for multiple characters.
|
Use separate `KeyPress` actions for multiple characters,
|
||||||
If Solaar can determine the current modifier keys,
|
i.e., don't use a single `KeyPress` like 'a+b'.
|
||||||
any key symbols that correspond to these modifier keys are not pressed.
|
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.
|
Simulating input in Linux is complex.
|
||||||
Solaar has to try to determine which keyboard key corresponds to which input character as it cannot directly
|
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.
|
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.
|
A `MouseScroll` action takes a sequence of two numbers and simulates a horizontal and vertical mouse scroll of these amounts.
|
||||||
|
|
|
@ -836,14 +836,14 @@ class KeyPress(Action):
|
||||||
def keysym_to_keycode(self, keysym, modifiers): # maybe should take shift into account
|
def keysym_to_keycode(self, keysym, modifiers): # maybe should take shift into account
|
||||||
group = kbdgroup() or 0
|
group = kbdgroup() or 0
|
||||||
keycodes = gkeymap.get_entries_for_keyval(keysym)
|
keycodes = gkeymap.get_entries_for_keyval(keysym)
|
||||||
if len(keycodes.keys) == 1:
|
(keycode, level) = (None, None)
|
||||||
k = keycodes.keys[0]
|
for k in keycodes.keys:
|
||||||
return k.keycode
|
if (group == k.group or len(keycodes.keys) == 1) and k.keycode < 256 and (level is None or k.level < level):
|
||||||
else:
|
keycode = k.keycode
|
||||||
for k in keycodes.keys:
|
level = k.level
|
||||||
if group is None or group == k.group:
|
if keycode is None:
|
||||||
return k.keycode
|
|
||||||
_log.warn('rule KeyPress key symbol not currently available %s', self)
|
_log.warn('rule KeyPress key symbol not currently available %s', self)
|
||||||
|
return (keycode, level)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'KeyPress: ' + ' '.join(self.key_names)
|
return 'KeyPress: ' + ' '.join(self.key_names)
|
||||||
|
@ -852,17 +852,29 @@ class KeyPress(Action):
|
||||||
code = modifier_code(k)
|
code = modifier_code(k)
|
||||||
return not (code is not None and modifiers & (1 << code))
|
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):
|
def keyDown(self, keysyms, modifiers):
|
||||||
for k in keysyms:
|
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):
|
if keycode and self.needed(keycode, modifiers):
|
||||||
|
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 = self.keysym_to_keycode(k, modifiers)
|
(keycode, level) = self.keysym_to_keycode(k, modifiers)
|
||||||
if keycode and self.needed(keycode, modifiers):
|
if keycode and self.needed(keycode, modifiers):
|
||||||
simulate_key(keycode, _KEY_RELEASE)
|
simulate_key(keycode, _KEY_RELEASE)
|
||||||
|
self.mods(level, modifiers, _KEY_RELEASE)
|
||||||
|
|
||||||
def evaluate(self, feature, notification, device, status, last_result):
|
def evaluate(self, feature, notification, device, status, last_result):
|
||||||
if gkeymap:
|
if gkeymap:
|
||||||
|
|
Loading…
Reference in New Issue