From 8b438f7b51013a6494f385e26dd061e050a65f68 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 31 Jul 2022 15:34:03 -0500 Subject: [PATCH] keyboard: Only send SDL_KEYMAPCHANGED when the keymap actually changes --- src/events/SDL_keyboard.c | 20 ++++++++++++++++---- src/events/SDL_keyboard_c.h | 2 +- src/video/android/SDL_androidkeyboard.c | 2 +- src/video/cocoa/SDL_cocoakeyboard.m | 5 +---- src/video/directfb/SDL_DirectFB_events.c | 4 ++-- src/video/wayland/SDL_waylandevents.c | 3 +-- src/video/windows/SDL_windowsevents.c | 3 +-- src/video/windows/SDL_windowskeyboard.c | 6 +++--- src/video/windows/SDL_windowskeyboard.h | 2 +- src/video/x11/SDL_x11events.c | 6 ++---- src/video/x11/SDL_x11keyboard.c | 6 +++--- src/video/x11/SDL_x11keyboard.h | 2 +- 12 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c index aa75f5d82..9a8c4033f 100644 --- a/src/events/SDL_keyboard.c +++ b/src/events/SDL_keyboard.c @@ -590,24 +590,36 @@ SDL_GetDefaultKeymap(SDL_Keycode * keymap) } void -SDL_SetKeymap(int start, SDL_Keycode * keys, int length) +SDL_SetKeymap(int start, SDL_Keycode * keys, int length, SDL_bool send_event) { SDL_Keyboard *keyboard = &SDL_keyboard; SDL_Scancode scancode; + SDL_Keycode normalized_keymap[SDL_NUM_SCANCODES]; if (start < 0 || start + length > SDL_NUM_SCANCODES) { return; } - SDL_memcpy(&keyboard->keymap[start], keys, sizeof(*keys) * length); + SDL_memcpy(&normalized_keymap[start], keys, sizeof(*keys) * length); /* The number key scancodes always map to the number key keycodes. * On AZERTY layouts these technically are symbols, but users (and games) * always think of them and view them in UI as number keys. */ - keyboard->keymap[SDL_SCANCODE_0] = SDLK_0; + normalized_keymap[SDL_SCANCODE_0] = SDLK_0; for (scancode = SDL_SCANCODE_1; scancode <= SDL_SCANCODE_9; ++scancode) { - keyboard->keymap[scancode] = SDLK_1 + (scancode - SDL_SCANCODE_1); + normalized_keymap[scancode] = SDLK_1 + (scancode - SDL_SCANCODE_1); + } + + /* If the mapping didn't really change, we're done here */ + if (!SDL_memcmp(&keyboard->keymap[start], &normalized_keymap[start], sizeof(*keys) * length)) { + return; + } + + SDL_memcpy(&keyboard->keymap[start], &normalized_keymap[start], sizeof(*keys) * length); + + if (send_event) { + SDL_SendKeymapChangedEvent(); } } diff --git a/src/events/SDL_keyboard_c.h b/src/events/SDL_keyboard_c.h index beee8276d..e911312d0 100644 --- a/src/events/SDL_keyboard_c.h +++ b/src/events/SDL_keyboard_c.h @@ -33,7 +33,7 @@ extern int SDL_KeyboardInit(void); extern void SDL_GetDefaultKeymap(SDL_Keycode * keymap); /* Set the mapping of scancode to key codes */ -extern void SDL_SetKeymap(int start, SDL_Keycode * keys, int length); +extern void SDL_SetKeymap(int start, SDL_Keycode * keys, int length, SDL_bool send_event); /* Set a platform-dependent key name, overriding the default platform-agnostic name. Encoded as UTF-8. The string is not copied, thus the pointer given to diff --git a/src/video/android/SDL_androidkeyboard.c b/src/video/android/SDL_androidkeyboard.c index 7098d2e6b..e120360ea 100644 --- a/src/video/android/SDL_androidkeyboard.c +++ b/src/video/android/SDL_androidkeyboard.c @@ -36,7 +36,7 @@ void Android_InitKeyboard(void) /* Add default scancode to key mapping */ SDL_GetDefaultKeymap(keymap); - SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES); + SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES, SDL_FALSE); } static SDL_Scancode Android_Keycodes[] = { diff --git a/src/video/cocoa/SDL_cocoakeyboard.m b/src/video/cocoa/SDL_cocoakeyboard.m index fd96ea3ce..02c99e8e7 100644 --- a/src/video/cocoa/SDL_cocoakeyboard.m +++ b/src/video/cocoa/SDL_cocoakeyboard.m @@ -439,10 +439,7 @@ UpdateKeymap(SDL_VideoData *data, SDL_bool send_event) keymap[scancode] = s[0]; } } - SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES); - if (send_event) { - SDL_SendKeymapChangedEvent(); - } + SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES, send_event); return; } diff --git a/src/video/directfb/SDL_DirectFB_events.c b/src/video/directfb/SDL_DirectFB_events.c index e6ca47ad3..4e0ec4d9f 100644 --- a/src/video/directfb/SDL_DirectFB_events.c +++ b/src/video/directfb/SDL_DirectFB_events.c @@ -698,9 +698,9 @@ EnumKeyboards(DFBInputDeviceID device_id, SDL_GetDefaultKeymap(keymap); #if USE_MULTI_API - SDL_SetKeymap(devdata->num_keyboard, 0, keymap, SDL_NUM_SCANCODES); + SDL_SetKeymap(devdata->num_keyboard, 0, keymap, SDL_NUM_SCANCODES, SDL_FALSE); #else - SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES); + SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES, SDL_FALSE); #endif devdata->num_keyboard++; diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index 08a7e1a3e..2b547faf6 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -1111,8 +1111,7 @@ keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, WAYLAND_xkb_keymap_key_for_each(input->xkb.keymap, Wayland_keymap_iter, &keymap); - SDL_SetKeymap(0, keymap.keymap, SDL_NUM_SCANCODES); - SDL_SendKeymapChangedEvent(); + SDL_SetKeymap(0, keymap.keymap, SDL_NUM_SCANCODES, SDL_TRUE); } static void diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index 60e80a8ce..4a1cfda89 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -1044,8 +1044,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) #ifdef WM_INPUTLANGCHANGE case WM_INPUTLANGCHANGE: { - WIN_UpdateKeymap(); - SDL_SendKeymapChangedEvent(); + WIN_UpdateKeymap(SDL_TRUE); } returnCode = 1; break; diff --git a/src/video/windows/SDL_windowskeyboard.c b/src/video/windows/SDL_windowskeyboard.c index ac17fdf49..9ff31d79c 100644 --- a/src/video/windows/SDL_windowskeyboard.c +++ b/src/video/windows/SDL_windowskeyboard.c @@ -102,7 +102,7 @@ WIN_InitKeyboard(_THIS) data->ime_uielemsink = 0; data->ime_ippasink = 0; - WIN_UpdateKeymap(); + WIN_UpdateKeymap(SDL_FALSE); SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu"); SDL_SetScancodeName(SDL_SCANCODE_LGUI, "Left Windows"); @@ -115,7 +115,7 @@ WIN_InitKeyboard(_THIS) } void -WIN_UpdateKeymap() +WIN_UpdateKeymap(SDL_bool send_event) { int i; SDL_Scancode scancode; @@ -152,7 +152,7 @@ WIN_UpdateKeymap() } } - SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES); + SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES, send_event); } void diff --git a/src/video/windows/SDL_windowskeyboard.h b/src/video/windows/SDL_windowskeyboard.h index 57c4ffaf9..c9b5e10a6 100644 --- a/src/video/windows/SDL_windowskeyboard.h +++ b/src/video/windows/SDL_windowskeyboard.h @@ -24,7 +24,7 @@ #define SDL_windowskeyboard_h_ extern void WIN_InitKeyboard(_THIS); -extern void WIN_UpdateKeymap(void); +extern void WIN_UpdateKeymap(SDL_bool send_event); extern void WIN_QuitKeyboard(_THIS); extern void WIN_ResetDeadKeys(void); diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index 6e3c0679b..b347b079b 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -842,8 +842,7 @@ X11_DispatchEvent(_THIS, XEvent *xevent) X11_XRefreshKeyboardMapping(&xevent->xmapping); } - X11_UpdateKeymap(_this); - SDL_SendKeymapChangedEvent(); + X11_UpdateKeymap(_this, SDL_TRUE); } else if (xevent->type == PropertyNotify && videodata && videodata->windowlist) { char* name_of_atom = X11_XGetAtomName(display, xevent->xproperty.atom); @@ -1470,8 +1469,7 @@ X11_DispatchEvent(_THIS, XEvent *xevent) icon). Since it changes the XKLAVIER_STATE property, we notice and reinit our keymap here. This might not be the right approach, but it seems to work. */ - X11_UpdateKeymap(_this); - SDL_SendKeymapChangedEvent(); + X11_UpdateKeymap(_this, SDL_TRUE); } else if (xevent->xproperty.atom == videodata->_NET_FRAME_EXTENTS) { Atom type; int format; diff --git a/src/video/x11/SDL_x11keyboard.c b/src/video/x11/SDL_x11keyboard.c index 6da6c7d23..c14e13d1c 100644 --- a/src/video/x11/SDL_x11keyboard.c +++ b/src/video/x11/SDL_x11keyboard.c @@ -394,7 +394,7 @@ X11_InitKeyboard(_THIS) } } - X11_UpdateKeymap(_this); + X11_UpdateKeymap(_this, SDL_FALSE); SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu"); @@ -408,7 +408,7 @@ X11_InitKeyboard(_THIS) } void -X11_UpdateKeymap(_THIS) +X11_UpdateKeymap(_THIS, SDL_bool send_event) { SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; int i; @@ -468,7 +468,7 @@ X11_UpdateKeymap(_THIS) } } } - SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES); + SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES, send_event); } void diff --git a/src/video/x11/SDL_x11keyboard.h b/src/video/x11/SDL_x11keyboard.h index 9e20ae12e..4ce41069b 100644 --- a/src/video/x11/SDL_x11keyboard.h +++ b/src/video/x11/SDL_x11keyboard.h @@ -24,7 +24,7 @@ #define SDL_x11keyboard_h_ extern int X11_InitKeyboard(_THIS); -extern void X11_UpdateKeymap(_THIS); +extern void X11_UpdateKeymap(_THIS, SDL_bool send_event); extern void X11_QuitKeyboard(_THIS); extern void X11_StartTextInput(_THIS); extern void X11_StopTextInput(_THIS);