From 4262fb182b2b51fd0ec8bec30671eb3babe94cb0 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Thu, 9 May 2024 15:02:06 -0700 Subject: xwayland: Release keys on keyboard `enter` event if `leave` wasn't received The code here assumed a `leave` event always occurs between two `enter` events. On Sway (and presumably other compositors) this happens even if the client has destroyed the `wl_surface`, but the client gets a null `surface` here. (Which presumably on on the wire is the id of the destroyed surface.) This seems like a bad thing to rely on, and is easy to avoid. But if this is correct to assume, the Wayland protocol should be explicit about this. (cherry picked from commit 386b54fbe95711e6ecb5c23cfdbf25a1571acf7b) Part-of: --- hw/xwayland/xwayland-input.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c index d23f284b9..5e4b78469 100644 --- a/hw/xwayland/xwayland-input.c +++ b/hw/xwayland/xwayland-input.c @@ -1213,6 +1213,10 @@ keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, xwl_seat->xwl_screen->serial = serial; xwl_seat->keyboard_focus = surface; + /* If `leave` wasn't sent (for a destroyed surface), release keys here. */ + wl_array_for_each(k, &xwl_seat->keys) + QueueKeyboardEvents(xwl_seat->keyboard, LeaveNotify, *k + 8); + wl_array_copy(&xwl_seat->keys, keys); wl_array_for_each(k, &xwl_seat->keys) QueueKeyboardEvents(xwl_seat->keyboard, EnterNotify, *k + 8); @@ -1227,6 +1231,7 @@ xwl_seat_leave_kbd(struct xwl_seat *xwl_seat) wl_array_for_each(k, &xwl_seat->keys) QueueKeyboardEvents(xwl_seat->keyboard, LeaveNotify, *k + 8); + xwl_seat->keys.size = 0; xwl_seat->keyboard_focus = NULL; -- cgit v1.2.3