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 386b54fbe9)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1635>
This commit is contained in:
Ian Douglas Scott 2024-05-09 15:02:06 -07:00 committed by Olivier Fourdan
parent 54a591b9b8
commit 4262fb182b

View file

@ -1213,6 +1213,10 @@ keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
xwl_seat->xwl_screen->serial = serial; xwl_seat->xwl_screen->serial = serial;
xwl_seat->keyboard_focus = surface; 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_copy(&xwl_seat->keys, keys);
wl_array_for_each(k, &xwl_seat->keys) wl_array_for_each(k, &xwl_seat->keys)
QueueKeyboardEvents(xwl_seat->keyboard, EnterNotify, *k + 8); 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) wl_array_for_each(k, &xwl_seat->keys)
QueueKeyboardEvents(xwl_seat->keyboard, LeaveNotify, *k + 8); QueueKeyboardEvents(xwl_seat->keyboard, LeaveNotify, *k + 8);
xwl_seat->keys.size = 0;
xwl_seat->keyboard_focus = NULL; xwl_seat->keyboard_focus = NULL;