key-bindings: try all bindings in translated mode before matching untranslated, and then finally raw

When trying to match key bindings, we do three types of matching:

* Match the _translated_ symbol (e.g. Control+C)
* Match the _untranslated_ symbol (e.g. Control+Shift+c)
* Match raw keyboard codes

This was done for *each* key binding. This meant we sometimes matched
a keybinding in raw mode, even though there was a
translated/untranslated binding that would match it too. All depending
on the internal order of the key binding list.

This patch changes it, so that we first try all bindings in translated
mode, then all bindings in untranslated mode, and finally all bindings
in raw mode.

Closes #1929
This commit is contained in:
Daniel Eklöf 2025-01-27 10:51:03 +01:00
parent 7a5353d18a
commit 8d6f0d0583
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
4 changed files with 52 additions and 9 deletions

17
input.c
View file

@ -1582,21 +1582,25 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
* User configurable bindings
*/
if (pressed) {
/* Match translated symbol */
tll_foreach(bindings->key, it) {
const struct key_binding *bind = &it->item;
/* Match translated symbol */
if (bind->k.sym == sym &&
bind->mods == (mods & ~consumed) &&
execute_binding(seat, term, bind, serial, 1))
{
goto maybe_repeat;
}
}
/* Match untranslated symbols */
tll_foreach(bindings->key, it) {
const struct key_binding *bind = &it->item;
if (bind->mods != mods)
continue;
/* Match untranslated symbols */
for (size_t i = 0; i < raw_count; i++) {
if (bind->k.sym == raw_syms[i] &&
execute_binding(seat, term, bind, serial, 1))
@ -1604,8 +1608,15 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
goto maybe_repeat;
}
}
}
/* Match raw key code */
tll_foreach(bindings->key, it) {
const struct key_binding *bind = &it->item;
if (bind->mods != mods)
continue;
/* Match raw key code */
tll_foreach(bind->k.key_codes, code) {
if (code->item == key &&
execute_binding(seat, term, bind, serial, 1))