From 8fda4231cfbba75704c4bb9461d42ce8240f233f Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Fri, 3 Oct 2025 13:55:52 -0400 Subject: [PATCH] wayland: Optimize the legacy key level fallback function When iterating over the keymap entries, a valid xkb state object has already been allocated, so use that instead of allocating/destroying a new state object for every lookup, which avoids a calloc/free operation inside libxkbcommon. Any state set by the level lookup function will be overwritten with valid state after keymap iteration has completed. --- src/video/wayland/SDL_waylandevents.c | 50 ++++++++++++--------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index c52b8b5586..d1f3c485dd 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -1429,38 +1429,34 @@ static size_t xkb_legacy_get_mods_for_level(SDL_WaylandSeat *seat, xkb_keycode_t } size_t mask_idx = 0; - struct xkb_state *state = WAYLAND_xkb_state_new(seat->keyboard.xkb.keymap); - if (state) { - const xkb_mod_mask_t keymod_masks[] = { - 0, - seat->keyboard.xkb.shift_mask, - seat->keyboard.xkb.caps_mask, - seat->keyboard.xkb.shift_mask | seat->keyboard.xkb.caps_mask, - seat->keyboard.xkb.level3_mask, - seat->keyboard.xkb.level3_mask | seat->keyboard.xkb.shift_mask, - seat->keyboard.xkb.level3_mask | seat->keyboard.xkb.caps_mask, - seat->keyboard.xkb.level3_mask | seat->keyboard.xkb.shift_mask | seat->keyboard.xkb.caps_mask, - seat->keyboard.xkb.level5_mask, - seat->keyboard.xkb.level5_mask | seat->keyboard.xkb.shift_mask, - seat->keyboard.xkb.level5_mask | seat->keyboard.xkb.caps_mask, - seat->keyboard.xkb.level5_mask | seat->keyboard.xkb.shift_mask | seat->keyboard.xkb.caps_mask - }; - const xkb_mod_mask_t pressed_mod_mask = seat->keyboard.xkb.shift_mask | seat->keyboard.xkb.level3_mask | seat->keyboard.xkb.level5_mask; - const xkb_mod_mask_t locked_mod_mask = seat->keyboard.xkb.caps_mask; + const xkb_mod_mask_t keymod_masks[] = { + 0, + seat->keyboard.xkb.shift_mask, + seat->keyboard.xkb.caps_mask, + seat->keyboard.xkb.shift_mask | seat->keyboard.xkb.caps_mask, + seat->keyboard.xkb.level3_mask, + seat->keyboard.xkb.level3_mask | seat->keyboard.xkb.shift_mask, + seat->keyboard.xkb.level3_mask | seat->keyboard.xkb.caps_mask, + seat->keyboard.xkb.level3_mask | seat->keyboard.xkb.shift_mask | seat->keyboard.xkb.caps_mask, + seat->keyboard.xkb.level5_mask, + seat->keyboard.xkb.level5_mask | seat->keyboard.xkb.shift_mask, + seat->keyboard.xkb.level5_mask | seat->keyboard.xkb.caps_mask, + seat->keyboard.xkb.level5_mask | seat->keyboard.xkb.shift_mask | seat->keyboard.xkb.caps_mask + }; + const xkb_mod_mask_t pressed_mod_mask = seat->keyboard.xkb.shift_mask | seat->keyboard.xkb.level3_mask | seat->keyboard.xkb.level5_mask; + const xkb_mod_mask_t locked_mod_mask = seat->keyboard.xkb.caps_mask; - for (size_t i = 0; i < SDL_arraysize(keymod_masks); ++i) { - WAYLAND_xkb_state_update_mask(state, keymod_masks[i] & pressed_mod_mask, 0, keymod_masks[i] & locked_mod_mask, 0, 0, layout); - if (WAYLAND_xkb_state_key_get_level(state, key, layout) == level) { - masks_out[mask_idx] = keymod_masks[i]; + for (size_t i = 0; i < SDL_arraysize(keymod_masks); ++i) { + WAYLAND_xkb_state_update_mask(seat->keyboard.xkb.state, keymod_masks[i] & pressed_mod_mask, 0, keymod_masks[i] & locked_mod_mask, 0, 0, layout); + if (WAYLAND_xkb_state_key_get_level(seat->keyboard.xkb.state, key, layout) == level) { + masks_out[mask_idx] = keymod_masks[i]; - if (++mask_idx == masks_size) { - break; - } + if (++mask_idx == masks_size) { + break; } } - - WAYLAND_xkb_state_unref(state); } + return mask_idx; } #endif