Commit 4a06cc0f75af431d1eb05e4d5cbbdd34bdc1e1fc

Frank Praznik 2022-09-22T13:03:09

wayland: Apply modifier changes to the text of repeated keys The text component of a repeated keystroke is initially set when a key is first pressed and the cached value remains static until the repeated key is released and another repeatable key is pressed. If the state of a modifier such as shift or capslock is changed while a key is being repeated, the text emitted will not have the modifier applied to it until the repeated key is released and pressed again. Update the text to be repeated by a key if a modifier is changed while a key is actively being repeated.

diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
index 308e41a..94b13c1 100644
--- a/src/video/wayland/SDL_waylandevents.c
+++ b/src/video/wayland/SDL_waylandevents.c
@@ -253,6 +253,24 @@ keyboard_repeat_set(SDL_WaylandKeyboardRepeat* repeat_info, uint32_t key, uint32
     }
 }
 
+static uint32_t
+keyboard_repeat_get_key(SDL_WaylandKeyboardRepeat *repeat_info)
+{
+    if (repeat_info->is_initialized && repeat_info->is_key_down) {
+        return repeat_info->key;
+    }
+
+    return 0;
+}
+
+static void
+keyboard_repeat_set_text(SDL_WaylandKeyboardRepeat *repeat_info, const char text[8])
+{
+    if (repeat_info->is_initialized) {
+        SDL_memcpy(repeat_info->text, text, 8);
+    }
+}
+
 static SDL_bool keyboard_repeat_is_set(SDL_WaylandKeyboardRepeat* repeat_info) {
     return repeat_info->is_initialized && repeat_info->is_key_down;
 }
@@ -1048,7 +1066,9 @@ keyboard_input_get_text(char text[8], const struct SDL_WaylandInput *input, uint
 
 #ifdef SDL_USE_IME
     if (SDL_IME_ProcessKeyEvent(sym, key + 8, state)) {
-        *handled_by_ime = SDL_TRUE;
+        if (handled_by_ime) {
+            *handled_by_ime = SDL_TRUE;
+        }
         return SDL_TRUE;
     }
 #endif
@@ -1060,7 +1080,9 @@ keyboard_input_get_text(char text[8], const struct SDL_WaylandInput *input, uint
     if (input->xkb.compose_state && WAYLAND_xkb_compose_state_feed(input->xkb.compose_state, sym) == XKB_COMPOSE_FEED_ACCEPTED) {
         switch(WAYLAND_xkb_compose_state_get_status(input->xkb.compose_state)) {
             case XKB_COMPOSE_COMPOSING:
-                *handled_by_ime = SDL_TRUE;
+                if (handled_by_ime) {
+                    *handled_by_ime = SDL_TRUE;
+                }
                 return SDL_TRUE;
             case XKB_COMPOSE_CANCELLED:
             default:
@@ -1199,6 +1221,16 @@ keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
     SDL_ToggleModState(KMOD_NUM, modstate & input->xkb.idx_num);
     SDL_ToggleModState(KMOD_CAPS, modstate & input->xkb.idx_caps);
 
+    /* If a key is repeating, update the text to apply the modifier. */
+    if(keyboard_repeat_is_set(&input->keyboard_repeat)) {
+        char text[8];
+        const uint32_t key = keyboard_repeat_get_key(&input->keyboard_repeat);
+
+        if (keyboard_input_get_text(text, input, key, SDL_PRESSED, NULL)) {
+            keyboard_repeat_set_text(&input->keyboard_repeat, text);
+        }
+    }
+
     if (group == input->xkb.current_group) {
         return;
     }