mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-09-05 19:08:12 +00:00
wayland: Only create/destroy the compose table when necessary
Initializing the compose table is a very expensive operation, and only necessary if the locale envvar changed, which is often not the case when just changing the keymap, so don't destroy and recreate it whenever the keymap changes. The state only needs to be reset in this case.
This commit is contained in:
@@ -1495,7 +1495,6 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
|
||||
{
|
||||
SDL_WaylandSeat *seat = data;
|
||||
char *map_str;
|
||||
const char *locale;
|
||||
|
||||
if (!data) {
|
||||
close(fd);
|
||||
@@ -1588,7 +1587,7 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
|
||||
*/
|
||||
|
||||
// Look up the preferred locale, falling back to "C" as default
|
||||
locale = SDL_getenv("LC_ALL");
|
||||
const char *locale = SDL_getenv("LC_ALL");
|
||||
if (!locale) {
|
||||
locale = SDL_getenv("LC_CTYPE");
|
||||
if (!locale) {
|
||||
@@ -1599,26 +1598,38 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
|
||||
}
|
||||
}
|
||||
|
||||
// Set up XKB compose table
|
||||
if (seat->keyboard.xkb.compose_table != NULL) {
|
||||
WAYLAND_xkb_compose_table_unref(seat->keyboard.xkb.compose_table);
|
||||
seat->keyboard.xkb.compose_table = NULL;
|
||||
}
|
||||
seat->keyboard.xkb.compose_table = WAYLAND_xkb_compose_table_new_from_locale(seat->display->xkb_context,
|
||||
locale, XKB_COMPOSE_COMPILE_NO_FLAGS);
|
||||
if (seat->keyboard.xkb.compose_table) {
|
||||
// Set up XKB compose state
|
||||
if (seat->keyboard.xkb.compose_state != NULL) {
|
||||
WAYLAND_xkb_compose_state_unref(seat->keyboard.xkb.compose_state);
|
||||
seat->keyboard.xkb.compose_state = NULL;
|
||||
}
|
||||
seat->keyboard.xkb.compose_state = WAYLAND_xkb_compose_state_new(seat->keyboard.xkb.compose_table,
|
||||
XKB_COMPOSE_STATE_NO_FLAGS);
|
||||
if (!seat->keyboard.xkb.compose_state) {
|
||||
SDL_SetError("could not create XKB compose state");
|
||||
/* Set up the XKB compose table.
|
||||
*
|
||||
* This is a very slow operation, so it is only done during initialization,
|
||||
* or if the locale envvar changed during runtime.
|
||||
*/
|
||||
if (!seat->keyboard.current_locale || SDL_strcmp(seat->keyboard.current_locale, locale) != 0) {
|
||||
// Cache the current locale for later comparison.
|
||||
SDL_free(seat->keyboard.current_locale);
|
||||
seat->keyboard.current_locale = SDL_strdup(locale);
|
||||
|
||||
if (seat->keyboard.xkb.compose_table != NULL) {
|
||||
WAYLAND_xkb_compose_table_unref(seat->keyboard.xkb.compose_table);
|
||||
seat->keyboard.xkb.compose_table = NULL;
|
||||
}
|
||||
seat->keyboard.xkb.compose_table = WAYLAND_xkb_compose_table_new_from_locale(seat->display->xkb_context,
|
||||
locale, XKB_COMPOSE_COMPILE_NO_FLAGS);
|
||||
if (seat->keyboard.xkb.compose_table) {
|
||||
// Set up XKB compose state
|
||||
if (seat->keyboard.xkb.compose_state != NULL) {
|
||||
WAYLAND_xkb_compose_state_unref(seat->keyboard.xkb.compose_state);
|
||||
seat->keyboard.xkb.compose_state = NULL;
|
||||
}
|
||||
seat->keyboard.xkb.compose_state = WAYLAND_xkb_compose_state_new(seat->keyboard.xkb.compose_table,
|
||||
XKB_COMPOSE_STATE_NO_FLAGS);
|
||||
if (!seat->keyboard.xkb.compose_state) {
|
||||
SDL_SetError("could not create XKB compose state");
|
||||
WAYLAND_xkb_compose_table_unref(seat->keyboard.xkb.compose_table);
|
||||
seat->keyboard.xkb.compose_table = NULL;
|
||||
}
|
||||
}
|
||||
} else if (seat->keyboard.xkb.compose_state) {
|
||||
WAYLAND_xkb_compose_state_reset(seat->keyboard.xkb.compose_state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2216,6 +2227,8 @@ static void Wayland_SeatDestroyKeyboard(SDL_WaylandSeat *seat, bool send_event)
|
||||
}
|
||||
}
|
||||
|
||||
SDL_free(seat->keyboard.current_locale);
|
||||
|
||||
if (seat->keyboard.xkb.compose_state) {
|
||||
WAYLAND_xkb_compose_state_unref(seat->keyboard.xkb.compose_state);
|
||||
}
|
||||
|
@@ -76,6 +76,7 @@ typedef struct SDL_WaylandSeat
|
||||
struct zwp_keyboard_shortcuts_inhibitor_v1 *key_inhibitor;
|
||||
SDL_WindowData *focus;
|
||||
SDL_Keymap *sdl_keymap;
|
||||
char *current_locale;
|
||||
|
||||
SDL_WaylandKeyboardRepeat repeat;
|
||||
Uint64 highres_timestamp_ns;
|
||||
|
Reference in New Issue
Block a user