x11: Avoid excessive keymap reconstruction

KeymapNotify events happen on focus events, as well as when the keymap group changes. Query the current group and don't rebuild the keymap if it hasn't changed.

Note that some IME changes, such as activating intelligent Japanese or Chinese input methods on Gnome, will only trigger IBus activation, and won't send a keymap or group update as they use the existing layout.
This commit is contained in:
Frank Praznik
2024-06-24 16:39:20 -04:00
parent 94ae4e1513
commit f79d0adfc9
3 changed files with 14 additions and 4 deletions

View File

@@ -1131,7 +1131,17 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
printf("window %p: KeymapNotify!\n", data);
#endif
if (SDL_GetKeyboardFocus() != NULL) {
X11_UpdateKeymap(_this, SDL_TRUE);
#ifdef SDL_VIDEO_DRIVER_X11_HAS_XKBLOOKUPKEYSYM
if (videodata->xkb) {
XkbStateRec state;
if (X11_XkbGetState(videodata->display, XkbUseCoreKbd, &state) == Success) {
if (state.group != videodata->xkb_group) {
/* Only rebuild the keymap if the layout has changed. */
X11_UpdateKeymap(_this, SDL_TRUE);
}
}
}
#endif
X11_ReconcileKeyboardState(_this);
}
} else if (xevent->type == MappingNotify) {

View File

@@ -347,7 +347,6 @@ void X11_UpdateKeymap(SDL_VideoDevice *_this, SDL_bool send_event)
int i;
SDL_Scancode scancode;
SDL_Keymap *keymap;
unsigned char group = 0;
keymap = SDL_CreateKeymap();
@@ -357,7 +356,7 @@ void X11_UpdateKeymap(SDL_VideoDevice *_this, SDL_bool send_event)
X11_XkbGetUpdatedMap(data->display, XkbAllClientInfoMask, data->xkb);
if (X11_XkbGetState(data->display, XkbUseCoreKbd, &state) == Success) {
group = state.group;
data->xkb_group = state.group;
}
}
#endif
@@ -372,7 +371,7 @@ void X11_UpdateKeymap(SDL_VideoDevice *_this, SDL_bool send_event)
continue;
}
KeySym keysym = X11_KeyCodeToSym(_this, i, group, keymod_masks[m].xkb_mask);
KeySym keysym = X11_KeyCodeToSym(_this, i, data->xkb_group, keymod_masks[m].xkb_mask);
/* Note: The default SDL scancode table sets this to right alt instead of AltGr/Mode, so handle it separately. */
if (keysym != XK_ISO_Level3_Shift) {

View File

@@ -125,6 +125,7 @@ struct SDL_VideoData
XkbDescPtr xkb;
#endif
int xkb_event;
unsigned int xkb_group;
KeyCode filter_code;
Time filter_time;