From 2891f0821b27012242c30759308bd8eed83d3fe7 Mon Sep 17 00:00:00 2001
From: Ethan Lee <[EMAIL REDACTED]>
Date: Fri, 25 Mar 2022 02:49:49 -0400
Subject: [PATCH] wayland: Use xkb_keymap_mod to set mod state
---
src/video/wayland/SDL_waylandevents.c | 36 ++++++++++++---------------
src/video/wayland/SDL_waylandsym.h | 2 ++
2 files changed, 18 insertions(+), 20 deletions(-)
diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
index fbab0601fab..b5d4ad1cd9c 100644
--- a/src/video/wayland/SDL_waylandevents.c
+++ b/src/video/wayland/SDL_waylandevents.c
@@ -910,8 +910,6 @@ 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;
@@ -923,24 +921,6 @@ 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;
@@ -1076,10 +1056,26 @@ keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
{
struct SDL_WaylandInput *input = data;
Wayland_Keymap keymap;
+ xkb_mod_index_t shift, ctrl, alt, gui, num, caps;
+ uint32_t modstate = (mods_depressed | mods_latched | mods_locked);
+
+ shift = WAYLAND_xkb_keymap_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_SHIFT);
+ ctrl = WAYLAND_xkb_keymap_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_CTRL);
+ alt = WAYLAND_xkb_keymap_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_ALT);
+ gui = WAYLAND_xkb_keymap_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_LOGO);
+ num = WAYLAND_xkb_keymap_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_NUM);
+ caps = WAYLAND_xkb_keymap_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_CAPS);
WAYLAND_xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched,
mods_locked, 0, 0, group);
+ SDL_ToggleModState(KMOD_SHIFT, modstate & (1 << shift));
+ SDL_ToggleModState(KMOD_CTRL, modstate & (1 << ctrl));
+ SDL_ToggleModState(KMOD_CAPS, modstate & (1 << alt));
+ SDL_ToggleModState(KMOD_GUI, modstate & (1 << gui));
+ SDL_ToggleModState(KMOD_NUM, modstate & (1 << num));
+ SDL_ToggleModState(KMOD_CAPS, modstate & (1 << caps));
+
keymap.layout = group;
SDL_GetDefaultKeymap(keymap.keymap);
WAYLAND_xkb_keymap_key_for_each(input->xkb.keymap,
diff --git a/src/video/wayland/SDL_waylandsym.h b/src/video/wayland/SDL_waylandsym.h
index 35f4dc870a4..6891325c7d8 100644
--- a/src/video/wayland/SDL_waylandsym.h
+++ b/src/video/wayland/SDL_waylandsym.h
@@ -147,6 +147,8 @@ SDL_WAYLAND_SYM(int, xkb_keymap_key_get_syms_by_level, (struct xkb_keymap *,
xkb_layout_index_t,
const xkb_keysym_t **) )
SDL_WAYLAND_SYM(uint32_t, xkb_keysym_to_utf32, (xkb_keysym_t) )
+SDL_WAYLAND_SYM(uint32_t, xkb_keymap_mod_get_index, (struct xkb_keymap *,
+ const char *) )
#ifdef HAVE_LIBDECOR_H
SDL_WAYLAND_MODULE(WAYLAND_LIBDECOR)