]> git.mdlowis.com Git - proto/labwc.git/commitdiff
seat: prevent xwayland from using incorrect keymap (#1816)
authorHiroaki Yamamoto <hrak1529@gmail.com>
Tue, 14 May 2024 20:15:28 +0000 (05:15 +0900)
committerGitHub <noreply@github.com>
Tue, 14 May 2024 20:15:28 +0000 (21:15 +0100)
With commit cafdcd8e, the keyboard from the keyboard group is set to the
seat when the active keyboard is destroyed, but this broke `wtype`
against XWayland surfaces. This is likely because XWayland caches
keycodes from the compositor and convert them with the last keymap
received from the compositor. So when we run `wtype a` over a XWayland
surface, the keycode for `a` is cached by XWayland, the keymap from the
keyboard group is sent to XWayland, then Xwayland converts the keycode
using the keymap from the keyboard group, not the one `wtype` set.

This commit fixes this by setting the keyboard from the keyboard group
to the seat when the keyboard focus is moved to a surface, not when the
active keyboard is destroyed.

src/seat.c

index c16cdcda6e279d9624cde213e42212673f22a40e..34158f2f29e7b427134c05a4d23e92fc212a55ef 100644 (file)
@@ -31,19 +31,6 @@ input_device_destroy(struct wl_listener *listener, void *data)
                wl_list_remove(&keyboard->key.link);
                wl_list_remove(&keyboard->modifier.link);
                keyboard_cancel_keybind_repeat(keyboard);
-               /*
-                * If the active keyboard on the seat is destroyed, fall back
-                * to the keyboard from keyboard group so we can respond to
-                * wl_seat.get_keyboard requests with wl_keyboard.keymap event.
-                * This prevents Chromium from crashing when started just after
-                * the active keyboard is destroyed.
-                */
-               struct wlr_keyboard *active_keyboard =
-                       wlr_seat_get_keyboard(input->seat->seat);
-               if (!active_keyboard || active_keyboard == keyboard->wlr_keyboard) {
-                       wlr_seat_set_keyboard(input->seat->seat,
-                               &input->seat->keyboard_group->keyboard);
-               }
        }
        free(input);
 }
@@ -648,6 +635,15 @@ seat_focus(struct seat *seat, struct wlr_surface *surface, bool is_lock_surface)
                return;
        }
 
+       if (!wlr_seat_get_keyboard(seat->seat)) {
+               /*
+                * wlr_seat_keyboard_notify_enter() sends wl_keyboard.modifiers,
+                * but it may crash some apps (e.g. Chromium) if
+                * wl_keyboard.keymap is not sent beforehand.
+                */
+               wlr_seat_set_keyboard(seat->seat, &seat->keyboard_group->keyboard);
+       }
+
        /*
         * Key events associated with keybindings (both pressed and released)
         * are not sent to clients. When changing surface-focus it is therefore