SDL: wayland: Update xkbcommon to avoid using deprecated modifier names

From c764e8864bc1df4288ec5546e39ac8eb63263ccc Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Sat, 31 May 2025 12:33:19 -0400
Subject: [PATCH] wayland: Update xkbcommon to avoid using deprecated modifier
 names

xkbcommon 1.10.0 declared certain modifier names to be deprecated, and the current plan is to remove them in 1.12.0. Use the new recommended names and modifier mask retrieval function when building against version 1.10.0 and higher.
---
 cmake/sdlchecks.cmake                         | 12 ++++++++++++
 include/build_config/SDL_build_config.h.cmake |  5 +++++
 src/video/wayland/SDL_waylanddyn.h            |  5 +++++
 src/video/wayland/SDL_waylandevents.c         | 11 +++++++++++
 src/video/wayland/SDL_waylandsym.h            |  3 +++
 5 files changed, 36 insertions(+)

diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake
index 42e87036f92c1..cbebf9ede2dd2 100644
--- a/cmake/sdlchecks.cmake
+++ b/cmake/sdlchecks.cmake
@@ -594,6 +594,18 @@ macro(CheckWayland)
         sdl_link_dependency(wayland LIBS PkgConfig::PC_WAYLAND PKG_CONFIG_PREFIX PC_WAYLAND PKG_CONFIG_SPECS ${WAYLAND_PKG_CONFIG_SPEC})
       endif()
 
+      # xkbcommon doesn't provide internal version defines, so generate them here.
+      if (PC_WAYLAND_xkbcommon_VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)")
+        set(SDL_XKBCOMMON_VERSION_MAJOR ${CMAKE_MATCH_1})
+        set(SDL_XKBCOMMON_VERSION_MINOR ${CMAKE_MATCH_2})
+        set(SDL_XKBCOMMON_VERSION_PATCH ${CMAKE_MATCH_3})
+      else()
+        message(WARNING "Failed to parse xkbcommon version; defaulting to lowest supported (0.5.0)")
+        set(SDL_XKBCOMMON_VERSION_MAJOR 0)
+        set(SDL_XKBCOMMON_VERSION_MINOR 5)
+        set(SDL_XKBCOMMON_VERSION_PATCH 0)
+      endif()
+
       if(SDL_WAYLAND_LIBDECOR)
         set(LibDecor_PKG_CONFIG_SPEC libdecor-0)
         pkg_check_modules(PC_LIBDECOR IMPORTED_TARGET ${LibDecor_PKG_CONFIG_SPEC})
diff --git a/include/build_config/SDL_build_config.h.cmake b/include/build_config/SDL_build_config.h.cmake
index 4d013c108c3ed..3cd00ed956451 100644
--- a/include/build_config/SDL_build_config.h.cmake
+++ b/include/build_config/SDL_build_config.h.cmake
@@ -548,6 +548,11 @@
 #cmakedefine SDL_VIDEO_VITA_PVR 1
 #cmakedefine SDL_VIDEO_VITA_PVR_OGL 1
 
+/* xkbcommon version info */
+#define SDL_XKBCOMMON_VERSION_MAJOR @SDL_XKBCOMMON_VERSION_MAJOR@
+#define SDL_XKBCOMMON_VERSION_MINOR @SDL_XKBCOMMON_VERSION_MINOR@
+#define SDL_XKBCOMMON_VERSION_PATCH @SDL_XKBCOMMON_VERSION_PATCH@
+
 /* Libdecor version info */
 #define SDL_LIBDECOR_VERSION_MAJOR @SDL_LIBDECOR_VERSION_MAJOR@
 #define SDL_LIBDECOR_VERSION_MINOR @SDL_LIBDECOR_VERSION_MINOR@
diff --git a/src/video/wayland/SDL_waylanddyn.h b/src/video/wayland/SDL_waylanddyn.h
index fd85a7c2d92ef..8a2c8aba38842 100644
--- a/src/video/wayland/SDL_waylanddyn.h
+++ b/src/video/wayland/SDL_waylanddyn.h
@@ -59,6 +59,11 @@ enum libdecor_window_state;
      (WAYLAND_VERSION_MAJOR == x && WAYLAND_VERSION_MINOR > y) || \
      (WAYLAND_VERSION_MAJOR == x && WAYLAND_VERSION_MINOR == y && WAYLAND_VERSION_MICRO >= z))
 
+#define SDL_XKBCOMMON_CHECK_VERSION(x, y, z)                                  \
+    (SDL_XKBCOMMON_VERSION_MAJOR > x ||                                       \
+     (SDL_XKBCOMMON_VERSION_MAJOR == x && SDL_XKBCOMMON_VERSION_MINOR > y) || \
+     (SDL_XKBCOMMON_VERSION_MAJOR == x && SDL_XKBCOMMON_VERSION_MINOR == y && SDL_XKBCOMMON_VERSION_PATCH >= z))
+
 #ifdef HAVE_LIBDECOR_H
 #define SDL_LIBDECOR_CHECK_VERSION(x, y, z)                                 \
     (SDL_LIBDECOR_VERSION_MAJOR > x ||                                      \
diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
index e9325ac51d628..bfbc775c30d95 100644
--- a/src/video/wayland/SDL_waylandevents.c
+++ b/src/video/wayland/SDL_waylandevents.c
@@ -1489,6 +1489,16 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
         return;
     }
 
+#if SDL_XKBCOMMON_CHECK_VERSION(1, 10, 0)
+    seat->keyboard.xkb.idx_shift = WAYLAND_xkb_keymap_mod_get_mask(seat->keyboard.xkb.keymap, XKB_MOD_NAME_SHIFT);
+    seat->keyboard.xkb.idx_ctrl = WAYLAND_xkb_keymap_mod_get_mask(seat->keyboard.xkb.keymap, XKB_MOD_NAME_CTRL);
+    seat->keyboard.xkb.idx_alt = WAYLAND_xkb_keymap_mod_get_mask(seat->keyboard.xkb.keymap, XKB_VMOD_NAME_ALT);
+    seat->keyboard.xkb.idx_gui = WAYLAND_xkb_keymap_mod_get_mask(seat->keyboard.xkb.keymap, XKB_VMOD_NAME_SUPER);
+    seat->keyboard.xkb.idx_mod5 = WAYLAND_xkb_keymap_mod_get_mask(seat->keyboard.xkb.keymap, XKB_VMOD_NAME_LEVEL3);
+    seat->keyboard.xkb.idx_mod3 = WAYLAND_xkb_keymap_mod_get_mask(seat->keyboard.xkb.keymap, XKB_VMOD_NAME_LEVEL5);
+    seat->keyboard.xkb.idx_num = WAYLAND_xkb_keymap_mod_get_mask(seat->keyboard.xkb.keymap, XKB_VMOD_NAME_NUM);
+    seat->keyboard.xkb.idx_caps = WAYLAND_xkb_keymap_mod_get_mask(seat->keyboard.xkb.keymap, XKB_MOD_NAME_CAPS);
+#else
 #define GET_MOD_INDEX(mod) \
     WAYLAND_xkb_keymap_mod_get_index(seat->keyboard.xkb.keymap, XKB_MOD_NAME_##mod)
     seat->keyboard.xkb.idx_shift = 1 << GET_MOD_INDEX(SHIFT);
@@ -1500,6 +1510,7 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
     seat->keyboard.xkb.idx_num = 1 << GET_MOD_INDEX(NUM);
     seat->keyboard.xkb.idx_caps = 1 << GET_MOD_INDEX(CAPS);
 #undef GET_MOD_INDEX
+#endif
 
     if (seat->keyboard.xkb.state != NULL) {
         /* if there's already a state, throw it away rather than leaking it before
diff --git a/src/video/wayland/SDL_waylandsym.h b/src/video/wayland/SDL_waylandsym.h
index 846c876a87b71..64e6e44dad064 100644
--- a/src/video/wayland/SDL_waylandsym.h
+++ b/src/video/wayland/SDL_waylandsym.h
@@ -159,6 +159,9 @@ 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 *) )
 SDL_WAYLAND_SYM(const char *, xkb_keymap_layout_get_name, (struct xkb_keymap*, xkb_layout_index_t))
+#if SDL_XKBCOMMON_CHECK_VERSION(1, 10, 0)
+SDL_WAYLAND_SYM(xkb_mod_mask_t, xkb_keymap_mod_get_mask, (struct xkb_keymap*, const char*))
+#endif
 
 #ifdef HAVE_LIBDECOR_H
 SDL_WAYLAND_MODULE(WAYLAND_LIBDECOR)