Commit 6d9ca926265fdadfc1676b9cfef8b098b0ac5d29

Ethan Lee 2022-03-25T01:36:39

wayland: Enforce text capitalization manually, for remapped keymods

diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
index 1aac970..fbab060 100644
--- a/src/video/wayland/SDL_waylandevents.c
+++ b/src/video/wayland/SDL_waylandevents.c
@@ -910,6 +910,8 @@ keyboard_input_get_text(char text[8], const struct SDL_WaylandInput *input, uint
     SDL_WindowData *window = input->keyboard_focus;
     const xkb_keysym_t *syms;
     xkb_keysym_t sym;
+    SDL_Keymod mod;
+    SDL_bool caps;
 
     if (!window || window->keyboard_device != input || !input->xkb.state) {
         return SDL_FALSE;
@@ -921,6 +923,24 @@ keyboard_input_get_text(char text[8], const struct SDL_WaylandInput *input, uint
     }
     sym = syms[0];
 
+    /* Wayland is actually pretty cool and sends key codes based on presumed
+     * caps lock state, problem is that it isn't totally accurate if the key
+     * has been remapped, so we have to force caps for our purposes.
+     * -flibit
+     */
+    mod = SDL_GetModState();
+    caps = (
+        /* Caps lock without shift... */
+        ((mod & KMOD_CAPS) && !(mod & KMOD_SHIFT)) ||
+        /* No caps lock with shift... */
+        (!(mod & KMOD_CAPS) && (mod & KMOD_SHIFT))
+    );
+    if (caps) {
+        sym = toupper(sym);
+    } else {
+        sym = tolower(sym);
+    }
+
 #ifdef SDL_USE_IME
     if (SDL_IME_ProcessKeyEvent(sym, key + 8)) {
         *handled_by_ime = SDL_TRUE;