فهرست منبع

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.
Frank Praznik 2 هفته پیش
والد
کامیت
9c9bb9cec7
2فایلهای تغییر یافته به همراه33 افزوده شده و 19 حذف شده
  1. 32 19
      src/video/wayland/SDL_waylandevents.c
  2. 1 0
      src/video/wayland/SDL_waylandevents_c.h

+ 32 - 19
src/video/wayland/SDL_waylandevents.c

@@ -1495,7 +1495,6 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
 {
 {
     SDL_WaylandSeat *seat = data;
     SDL_WaylandSeat *seat = data;
     char *map_str;
     char *map_str;
-    const char *locale;
 
 
     if (!data) {
     if (!data) {
         close(fd);
         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
     // 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) {
     if (!locale) {
         locale = SDL_getenv("LC_CTYPE");
         locale = SDL_getenv("LC_CTYPE");
         if (!locale) {
         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);
             WAYLAND_xkb_compose_table_unref(seat->keyboard.xkb.compose_table);
             seat->keyboard.xkb.compose_table = NULL;
             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) {
     if (seat->keyboard.xkb.compose_state) {
         WAYLAND_xkb_compose_state_unref(seat->keyboard.xkb.compose_state);
         WAYLAND_xkb_compose_state_unref(seat->keyboard.xkb.compose_state);
     }
     }

+ 1 - 0
src/video/wayland/SDL_waylandevents_c.h

@@ -76,6 +76,7 @@ typedef struct SDL_WaylandSeat
         struct zwp_keyboard_shortcuts_inhibitor_v1 *key_inhibitor;
         struct zwp_keyboard_shortcuts_inhibitor_v1 *key_inhibitor;
         SDL_WindowData *focus;
         SDL_WindowData *focus;
         SDL_Keymap *sdl_keymap;
         SDL_Keymap *sdl_keymap;
+        char *current_locale;
 
 
         SDL_WaylandKeyboardRepeat repeat;
         SDL_WaylandKeyboardRepeat repeat;
         Uint64 highres_timestamp_ns;
         Uint64 highres_timestamp_ns;