diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h index 450cd473..d32d6e96 100644 --- a/include/wlr/types/wlr_keyboard.h +++ b/include/wlr/types/wlr_keyboard.h @@ -44,6 +44,7 @@ struct wlr_keyboard { xkb_mod_index_t mod_indexes[WLR_MODIFIER_COUNT]; uint32_t keycodes[WLR_KEYBOARD_KEYS_CAP]; + size_t num_keycodes; struct { xkb_mod_mask_t depressed; xkb_mod_mask_t latched; diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index 5ec8c043..6caf27f5 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -44,28 +45,46 @@ static void keyboard_modifier_update(struct wlr_keyboard *keyboard) { wl_signal_emit(&keyboard->events.modifiers, keyboard); } +// https://www.geeksforgeeks.org/move-zeroes-end-array/ +static size_t push_zeroes_to_end(uint32_t arr[], size_t n) { + size_t count = 0; + + for (size_t i = 0; i < n; i++) { + if (arr[i] != 0) { + arr[count++] = arr[i]; + } + } + + size_t ret = count; + + while (count < n) { + arr[count++] = 0; + } + + return ret; +} + static void keyboard_key_update(struct wlr_keyboard *keyboard, struct wlr_event_keyboard_key *event) { bool found = false; size_t i = 0; - for (; i < WLR_KEYBOARD_KEYS_CAP; ++i) { + for (; i < keyboard->num_keycodes; ++i) { if (keyboard->keycodes[i] == event->keycode) { found = true; break; } } - if (event->state == WLR_KEY_PRESSED && !found) { - for (size_t i = 0; i < WLR_KEYBOARD_KEYS_CAP; ++i) { - if (keyboard->keycodes[i] == 0) { - keyboard->keycodes[i] = event->keycode; - break; - } - } + if (event->state == WLR_KEY_PRESSED && !found && + keyboard->num_keycodes < WLR_KEYBOARD_KEYS_CAP) { + keyboard->keycodes[keyboard->num_keycodes++] = event->keycode; } if (event->state == WLR_KEY_RELEASED && found) { keyboard->keycodes[i] = 0; + keyboard->num_keycodes = push_zeroes_to_end(keyboard->keycodes, WLR_KEYBOARD_KEYS_CAP); } + + assert(keyboard->num_keycodes <= WLR_KEYBOARD_KEYS_CAP); } void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, diff --git a/types/wlr_seat.c b/types/wlr_seat.c index b69e666b..156ac142 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -874,11 +874,9 @@ void wlr_seat_keyboard_enter(struct wlr_seat *seat, struct wl_array keys; wl_array_init(&keys); - for (size_t i = 0; i < WLR_KEYBOARD_KEYS_CAP; ++i) { - if (keyboard->keycodes[i] != 0) { - uint32_t *p = wl_array_add(&keys, sizeof(uint32_t)); - *p = keyboard->keycodes[i]; - } + for (size_t i = 0; i < keyboard->num_keycodes; ++i) { + uint32_t *p = wl_array_add(&keys, sizeof(uint32_t)); + *p = keyboard->keycodes[i]; } uint32_t serial = wl_display_next_serial(seat->display); struct wl_resource *resource;