Skip to content

Commit 20e8ac0

Browse files
committed
wayland: Fix keymap changed event spam with non-latin keyboard layouts
The function SDL_GetCurrentKeymap() would return null instead of the actual bound keymap for non-latin layouts if certain mapping options were set. Add a parameter to ignore the keymap options and always return the actual bound keymap, which is needed in the Wayland backend to avoid spamming keymap changed events on every keystroke with certain layouts.
1 parent b8e055c commit 20e8ac0

File tree

4 files changed

+24
-19
lines changed

4 files changed

+24
-19
lines changed

src/events/SDL_keyboard.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -239,20 +239,22 @@ void SDL_ResetKeyboard(void)
239239
}
240240
}
241241

242-
SDL_Keymap *SDL_GetCurrentKeymap(void)
242+
SDL_Keymap *SDL_GetCurrentKeymap(bool ignore_options)
243243
{
244244
SDL_Keyboard *keyboard = &SDL_keyboard;
245245
SDL_Keymap *keymap = SDL_keyboard.keymap;
246246

247-
if (keymap && keymap->thai_keyboard) {
248-
// Thai keyboards are QWERTY plus Thai characters, use the default QWERTY keymap
249-
return NULL;
250-
}
247+
if (!ignore_options) {
248+
if (keymap && keymap->thai_keyboard) {
249+
// Thai keyboards are QWERTY plus Thai characters, use the default QWERTY keymap
250+
return NULL;
251+
}
251252

252-
if ((keyboard->keycode_options & KEYCODE_OPTION_LATIN_LETTERS) &&
253-
keymap && !keymap->latin_letters) {
254-
// We'll use the default QWERTY keymap
255-
return NULL;
253+
if ((keyboard->keycode_options & KEYCODE_OPTION_LATIN_LETTERS) &&
254+
keymap && !keymap->latin_letters) {
255+
// We'll use the default QWERTY keymap
256+
return NULL;
257+
}
256258
}
257259

258260
return keyboard->keymap;
@@ -490,7 +492,7 @@ SDL_Keycode SDL_GetKeyFromScancode(SDL_Scancode scancode, SDL_Keymod modstate, b
490492
SDL_Keyboard *keyboard = &SDL_keyboard;
491493

492494
if (key_event) {
493-
SDL_Keymap *keymap = SDL_GetCurrentKeymap();
495+
SDL_Keymap *keymap = SDL_GetCurrentKeymap(false);
494496
bool numlock = (modstate & SDL_KMOD_NUM) != 0;
495497
SDL_Keycode keycode;
496498

src/events/SDL_keymap.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,7 +1059,7 @@ const char *SDL_GetKeyName(SDL_Keycode key)
10591059
// but the key name is defined as the letter printed on that key,
10601060
// which is usually the shifted capital letter.
10611061
if (key > 0x7F || (key >= 'a' && key <= 'z')) {
1062-
SDL_Keymap *keymap = SDL_GetCurrentKeymap();
1062+
SDL_Keymap *keymap = SDL_GetCurrentKeymap(false);
10631063
SDL_Keymod modstate;
10641064
SDL_Scancode scancode = SDL_GetKeymapScancode(keymap, key, &modstate);
10651065
if (scancode != SDL_SCANCODE_UNKNOWN && !(modstate & SDL_KMOD_SHIFT)) {
@@ -1127,7 +1127,7 @@ SDL_Keycode SDL_GetKeyFromName(const char *name)
11271127
// SDL_Keycode is defined as the unshifted key on the keyboard,
11281128
// but the key name is defined as the letter printed on that key,
11291129
// which is usually the shifted capital letter.
1130-
SDL_Keymap *keymap = SDL_GetCurrentKeymap();
1130+
SDL_Keymap *keymap = SDL_GetCurrentKeymap(false);
11311131
SDL_Keymod modstate;
11321132
SDL_Scancode scancode = SDL_GetKeymapScancode(keymap, key, &modstate);
11331133
if (scancode != SDL_SCANCODE_UNKNOWN && (modstate & (SDL_KMOD_SHIFT | SDL_KMOD_CAPS))) {

src/events/SDL_keymap_c.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ typedef struct SDL_Keymap
3434
bool thai_keyboard;
3535
} SDL_Keymap;
3636

37-
SDL_Keymap *SDL_GetCurrentKeymap(void);
37+
/* This may return null even when a keymap is bound, depending on the current keyboard mapping options.
38+
* Set 'ignore_options' to true to always return the keymap that is actually bound.
39+
*/
40+
SDL_Keymap *SDL_GetCurrentKeymap(bool ignore_options);
3841
SDL_Keymap *SDL_CreateKeymap(bool auto_release);
3942
void SDL_SetKeymapEntry(SDL_Keymap *keymap, SDL_Scancode scancode, SDL_Keymod modstate, SDL_Keycode keycode);
4043
SDL_Keycode SDL_GetKeymapKeycode(SDL_Keymap *keymap, SDL_Scancode scancode, SDL_Keymod modstate);

src/video/wayland/SDL_waylandevents.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ int Wayland_WaitEventTimeout(SDL_VideoDevice *_this, Sint64 timeoutNS)
438438
// If key repeat is active, we'll need to cap our maximum wait time to handle repeats
439439
wl_list_for_each (seat, &d->seat_list, link) {
440440
if (keyboard_repeat_is_set(&seat->keyboard.repeat)) {
441-
if (seat->keyboard.sdl_keymap != SDL_GetCurrentKeymap()) {
441+
if (seat->keyboard.sdl_keymap != SDL_GetCurrentKeymap(true)) {
442442
SDL_SetKeymap(seat->keyboard.sdl_keymap, true);
443443
SDL_SetModState(seat->keyboard.pressed_modifiers | seat->keyboard.locked_modifiers);
444444
}
@@ -477,7 +477,7 @@ int Wayland_WaitEventTimeout(SDL_VideoDevice *_this, Sint64 timeoutNS)
477477
// If key repeat is active, we might have woken up to generate a key event
478478
if (key_repeat_active) {
479479
wl_list_for_each (seat, &d->seat_list, link) {
480-
if (seat->keyboard.sdl_keymap != SDL_GetCurrentKeymap()) {
480+
if (seat->keyboard.sdl_keymap != SDL_GetCurrentKeymap(true)) {
481481
SDL_SetKeymap(seat->keyboard.sdl_keymap, true);
482482
SDL_SetModState(seat->keyboard.pressed_modifiers | seat->keyboard.locked_modifiers);
483483
}
@@ -548,7 +548,7 @@ void Wayland_PumpEvents(SDL_VideoDevice *_this)
548548

549549
wl_list_for_each (seat, &d->seat_list, link) {
550550
if (keyboard_repeat_is_set(&seat->keyboard.repeat)) {
551-
if (seat->keyboard.sdl_keymap != SDL_GetCurrentKeymap()) {
551+
if (seat->keyboard.sdl_keymap != SDL_GetCurrentKeymap(true)) {
552552
SDL_SetKeymap(seat->keyboard.sdl_keymap, true);
553553
SDL_SetModState(seat->keyboard.pressed_modifiers | seat->keyboard.locked_modifiers);
554554
}
@@ -1820,7 +1820,7 @@ static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
18201820
Uint64 timestamp = SDL_GetTicksNS();
18211821
window->last_focus_event_time_ns = timestamp;
18221822

1823-
if (SDL_GetCurrentKeymap() != seat->keyboard.sdl_keymap) {
1823+
if (SDL_GetCurrentKeymap(true) != seat->keyboard.sdl_keymap) {
18241824
SDL_SetKeymap(seat->keyboard.sdl_keymap, true);
18251825
}
18261826

@@ -1970,7 +1970,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
19701970

19711971
Wayland_UpdateImplicitGrabSerial(seat, serial);
19721972

1973-
if (seat->keyboard.sdl_keymap != SDL_GetCurrentKeymap()) {
1973+
if (seat->keyboard.sdl_keymap != SDL_GetCurrentKeymap(true)) {
19741974
SDL_SetKeymap(seat->keyboard.sdl_keymap, true);
19751975
SDL_SetModState(seat->keyboard.pressed_modifiers | seat->keyboard.locked_modifiers);
19761976
}
@@ -2131,7 +2131,7 @@ static void Wayland_SeatDestroyKeyboard(SDL_WaylandSeat *seat, bool send_event)
21312131
SDL_RemoveKeyboard(seat->keyboard.sdl_id, send_event);
21322132

21332133
if (seat->keyboard.sdl_keymap) {
2134-
if (seat->keyboard.sdl_keymap == SDL_GetCurrentKeymap()) {
2134+
if (seat->keyboard.sdl_keymap == SDL_GetCurrentKeymap(true)) {
21352135
SDL_SetKeymap(NULL, false);
21362136
}
21372137
SDL_DestroyKeymap(seat->keyboard.sdl_keymap);

0 commit comments

Comments
 (0)