From 8b438f7b51013a6494f385e26dd061e050a65f68 Mon Sep 17 00:00:00 2001
From: Cameron Gutman <[EMAIL REDACTED]>
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 aa75f5d82a1..9a8c4033fe2 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 beee8276d7c..e911312d0e8 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 7098d2e6bd4..e120360ea30 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 fd96ea3ceb7..02c99e8e72a 100644
--- a/src/video/cocoa/SDL_cocoakeyboard.m
+++ b/src/video/cocoa/SDL_cocoakeyboard.m
@@ -439,10 +439,7 @@ - (NSArray *)validAttributesForMarkedText
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 e6ca47ad3e5..4e0ec4d9f66 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 08a7e1a3e1d..2b547faf673 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 60e80a8cec9..4a1cfda89d3 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 ac17fdf49b1..9ff31d79cf4 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 57c4ffaf923..c9b5e10a6f5 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 6e3c0679b63..b347b079b72 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 6da6c7d2313..c14e13d1c0c 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 9e20ae12ebe..4ce41069b7b 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);