From 399cb2f0de2dc840bddba71133a7b54a5ae69ac8 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Wed, 21 Sep 2022 13:20:39 -0400 Subject: [PATCH] wayland: Only clear the key repeat flag when the repeated key is released If multiple keys were simultaneously depressed and one was being repeated, the repeat flag was being cleared when any of the pressed keys were released, even if the released key wasn't the one being repeated. This tracks the key currently being repeated and only clears the repeat flag when the particular key being repeated is released. --- src/video/wayland/SDL_waylandevents.c | 11 ++++++++--- src/video/wayland/SDL_waylandevents_c.h | 1 + 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index 02c48bcca..ec2f514ee 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -233,12 +233,13 @@ keyboard_repeat_clear(SDL_WaylandKeyboardRepeat* repeat_info) { } static void -keyboard_repeat_set(SDL_WaylandKeyboardRepeat* repeat_info, uint32_t wl_press_time, +keyboard_repeat_set(SDL_WaylandKeyboardRepeat* repeat_info, uint32_t key, uint32_t wl_press_time, uint32_t scancode, SDL_bool has_text, char text[8]) { if (!repeat_info->is_initialized || !repeat_info->repeat_rate) { return; } repeat_info->is_key_down = SDL_TRUE; + repeat_info->key = key; repeat_info->wl_press_time = wl_press_time; repeat_info->sdl_press_time = SDL_GetTicks(); repeat_info->next_repeat_ms = repeat_info->repeat_delay; @@ -254,6 +255,10 @@ static SDL_bool keyboard_repeat_is_set(SDL_WaylandKeyboardRepeat* repeat_info) { return repeat_info->is_initialized && repeat_info->is_key_down; } +static SDL_bool keyboard_repeat_key_is_set(SDL_WaylandKeyboardRepeat* repeat_info, uint32_t key) { + return repeat_info->is_initialized && repeat_info->is_key_down && key == repeat_info->key; +} + void Wayland_SendWakeupEvent(_THIS, SDL_Window *window) { @@ -1085,7 +1090,7 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard, if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { has_text = keyboard_input_get_text(text, input, key, SDL_PRESSED, &handled_by_ime); } else { - if (keyboard_repeat_is_set(&input->keyboard_repeat)) { + if (keyboard_repeat_key_is_set(&input->keyboard_repeat, key)) { // Send any due key repeat events before stopping the repeat and generating the key up event // Compute time based on the Wayland time, as it reports when the release event happened // Using SDL_GetTicks would be wrong, as it would report when the release event is processed, @@ -1114,7 +1119,7 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard, } } if (input->xkb.keymap && WAYLAND_xkb_keymap_key_repeats(input->xkb.keymap, key + 8)) { - keyboard_repeat_set(&input->keyboard_repeat, time, scancode, has_text, text); + keyboard_repeat_set(&input->keyboard_repeat, key, time, scancode, has_text, text); } } } diff --git a/src/video/wayland/SDL_waylandevents_c.h b/src/video/wayland/SDL_waylandevents_c.h index d70fdee44..9d240d7bd 100644 --- a/src/video/wayland/SDL_waylandevents_c.h +++ b/src/video/wayland/SDL_waylandevents_c.h @@ -71,6 +71,7 @@ typedef struct { SDL_bool is_initialized; SDL_bool is_key_down; + uint32_t key; uint32_t wl_press_time; // Key press time as reported by the Wayland API uint32_t sdl_press_time; // Key press time expressed in SDL ticks uint32_t next_repeat_ms;