From 6574c82aedc8ce530af8c6a0ad8680ba6d7d1f4a Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Sat, 16 Aug 2025 13:17:36 -0400 Subject: [PATCH] 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. --- include/config/keybind.h | 3 ++ src/config/keybind.c | 73 ++++++++++++++++++++++++++-------------- src/input/keyboard.c | 13 +++---- 3 files changed, 56 insertions(+), 33 deletions(-) diff --git a/include/config/keybind.h b/include/config/keybind.h index 386839ee..3d923530 100644 --- a/include/config/keybind.h +++ b/include/config/keybind.h @@ -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 */ diff --git a/src/config/keybind.c b/src/config/keybind.c index 9003e5ee..2635b7bc 100644 --- a/src/config/keybind.c +++ b/src/config/keybind.c @@ -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; } } } diff --git a/src/input/keyboard.c b/src/input/keyboard.c index 8d1b9ae3..28ae0271 100644 --- a/src/input/keyboard.c +++ b/src/input/keyboard.c @@ -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; } } } -- 2.52.0