keybinds: add optional layoutDependent argument

This allows to define keybinds as layout dependent. E.g. keybinds
only trigger if the configured key exists in the currently active
keyboard layout. The keybind will also only trigger on the physical
key that is mapped to the configured key in the active layout.

By default the new argument is false which means all keybinds by
default are layout agnostic. This optional argument can be used
to restore the earlier default behavior of having keys layout
dependent.
This commit is contained in:
Consolatis 2023-09-11 15:15:37 +02:00
parent 6b80751010
commit c1c624daf0
4 changed files with 16 additions and 2 deletions

View file

@ -268,14 +268,22 @@ Therefore, where multiple objects of the same kind are required (for example
## KEYBOARD
*<keyboard><keybind key="">*
Define a key binding in the format *modifier-key*, where supported
*<keyboard><keybind key="" layoutDependent="">*
Define a *key* binding in the format *modifier-key*, where supported
modifiers include S (shift); C (control); A (alt); W (super). Unlike
Openbox, multiple space-separated key combinations and key-chains are
not supported. The application "wev" (wayland event viewer) is packaged
in a lot of distributions and can be used to view all available
keynames.
*layoutDependent* [yes|no]
Make this specific keybind depend on the currently active keyboard
layout. If enabled, a keybind using a key which does not exist in
the currently active layout will not be executed. The physical key
to trigger a keybind may also change along with the active layout.
If set to "no" (or is absent) the keybind will be layout agnostic.
Default is no.
*<keyboard><keybind key=""><action name="">*
Keybind action. See labwc-action(5)

View file

@ -14,6 +14,7 @@ struct keybind {
uint32_t modifiers;
xkb_keysym_t *keysyms;
size_t keysyms_len;
bool use_syms_only;
xkb_keycode_t keycodes[MAX_KEYCODES];
size_t keycodes_len;
int keycodes_layout;

View file

@ -59,6 +59,9 @@ update_keycodes_iter(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
/* Prevent storing keycodes from multiple layouts */
continue;
}
if (keybind->use_syms_only) {
continue;
}
for (int i = 0; i < nr_syms; i++) {
xkb_keysym_t sym = syms[i];
for (size_t j = 0; j < keybind->keysyms_len; j++) {

View file

@ -267,6 +267,8 @@ fill_keybind(char *nodename, char *content)
} else if (!current_keybind) {
wlr_log(WLR_ERROR, "expect <keybind key=\"\"> element first. "
"nodename: '%s' content: '%s'", nodename, content);
} else if (!strcasecmp(nodename, "layoutDependent")) {
set_bool(content, &current_keybind->use_syms_only);
} else if (!strcmp(nodename, "name.action")) {
current_keybind_action = action_create(content);
if (current_keybind_action) {