keybind: refactor update_keycodes_iter() to reduce nesting

update_keycodes_iter() currently has 4(!) levels of nested loops, which
makes the logic (especially the break/continue statements) difficult to
understand. The logic also appears to continue looping uselessly after
a given keycode has already been added to a keybind.

Refactor by adding some small utility functions:

- keybind_contains_keycode()
- keybind_contains_keysym()
- keybind_contains_any_keysym()

No functional change intended.
This commit is contained in:
John Lindgren 2025-08-16 13:17:36 -04:00 committed by Johan Malm
parent 28513cbdbe
commit 6574c82aed
3 changed files with 56 additions and 33 deletions

View file

@ -41,5 +41,8 @@ uint32_t parse_modifier(const char *symname);
bool keybind_the_same(struct keybind *a, struct keybind *b);
bool keybind_contains_keycode(struct keybind *keybind, xkb_keycode_t keycode);
bool keybind_contains_keysym(struct keybind *keybind, xkb_keysym_t keysym);
void keybind_update_keycodes(struct server *server);
#endif /* LABWC_KEYBIND_H */

View file

@ -49,6 +49,42 @@ keybind_the_same(struct keybind *a, struct keybind *b)
return true;
}
bool
keybind_contains_keycode(struct keybind *keybind, xkb_keycode_t keycode)
{
assert(keybind);
for (size_t i = 0; i < keybind->keycodes_len; i++) {
if (keybind->keycodes[i] == keycode) {
return true;
}
}
return false;
}
bool
keybind_contains_keysym(struct keybind *keybind, xkb_keysym_t keysym)
{
assert(keybind);
for (size_t i = 0; i < keybind->keysyms_len; i++) {
if (keybind->keysyms[i] == keysym) {
return true;
}
}
return false;
}
static bool
keybind_contains_any_keysym(struct keybind *keybind,
const xkb_keysym_t *syms, int nr_syms)
{
for (int i = 0; i < nr_syms; i++) {
if (keybind_contains_keysym(keybind, syms[i])) {
return true;
}
}
return false;
}
static void
update_keycodes_iter(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
{
@ -68,32 +104,19 @@ update_keycodes_iter(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
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++) {
if (sym != keybind->keysyms[j]) {
continue;
}
/* Found keycode for sym */
if (keybind->keycodes_len == MAX_KEYCODES) {
wlr_log(WLR_ERROR,
"Already stored %lu keycodes for keybind",
keybind->keycodes_len);
break;
}
bool keycode_exists = false;
for (size_t k = 0; k < keybind->keycodes_len; k++) {
if (keybind->keycodes[k] == key) {
keycode_exists = true;
break;
}
}
if (keycode_exists) {
continue;
}
keybind->keycodes[keybind->keycodes_len++] = key;
keybind->keycodes_layout = layout;
if (keybind_contains_any_keysym(keybind, syms, nr_syms)) {
if (keybind_contains_keycode(keybind, key)) {
/* Prevent storing the same keycode twice */
continue;
}
if (keybind->keycodes_len == MAX_KEYCODES) {
wlr_log(WLR_ERROR,
"Already stored %lu keycodes for keybind",
keybind->keycodes_len);
continue;
}
keybind->keycodes[keybind->keycodes_len++] = key;
keybind->keycodes_layout = layout;
}
}
}

View file

@ -219,17 +219,14 @@ match_keybinding_for_sym(struct server *server, uint32_t modifiers,
}
if (sym == XKB_KEY_NoSymbol) {
/* Use keycodes */
for (size_t i = 0; i < keybind->keycodes_len; i++) {
if (keybind->keycodes[i] == xkb_keycode) {
return keybind;
}
if (keybind_contains_keycode(keybind, xkb_keycode)) {
return keybind;
}
} else {
/* Use syms */
for (size_t i = 0; i < keybind->keysyms_len; i++) {
if (xkb_keysym_to_lower(sym) == keybind->keysyms[i]) {
return keybind;
}
if (keybind_contains_keysym(keybind,
xkb_keysym_to_lower(sym))) {
return keybind;
}
}
}