aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wlr/types/wlr_keyboard.h1
-rw-r--r--types/wlr_keyboard.c35
-rw-r--r--types/wlr_seat.c8
3 files changed, 31 insertions, 13 deletions
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 <string.h>
#include <sys/mman.h>
#include <unistd.h>
+#include <assert.h>
#include <wayland-server.h>
#include <wlr/types/wlr_keyboard.h>
#include <wlr/interfaces/wlr_keyboard.h>
@@ -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;