From 0525b9a5b9c40ec4dd384b8878cda85ef7401b94 Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Mon, 29 Jul 2024 17:43:45 +0200 Subject: [PATCH] xwayland/ei: Dequeue events when all caps are available Currently, we would start dequeuing events as soon as a device is resumed, regardless of its capabilities. If the capabilities are not available, we would just fallback to the regular XTEST code path and not use input emulation. As a result, it is very likely that we shall lose the first events until the compositor resumes first a device with the requested capabilities. To avoid that issue, start emulating only once we have the requested capabilities, if they match the seat capabilities. Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1732 Signed-off-by: Olivier Fourdan Part-of: --- hw/xwayland/xwayland-xtest.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/hw/xwayland/xwayland-xtest.c b/hw/xwayland/xwayland-xtest.c index c90f3e9b8..d8b0e018c 100644 --- a/hw/xwayland/xwayland-xtest.c +++ b/hw/xwayland/xwayland-xtest.c @@ -743,6 +743,20 @@ xwl_ei_update_caps(struct xwl_ei_client *xwl_ei_client, } } +static bool +xwl_ei_devices_are_ready(struct xwl_ei_client *xwl_ei_client) +{ + if ((xwl_ei_client->accept_keyboard || + !ei_seat_has_capability(xwl_ei_client->ei_seat, EI_DEVICE_CAP_KEYBOARD)) && + (xwl_ei_client->accept_pointer || + !ei_seat_has_capability(xwl_ei_client->ei_seat, EI_DEVICE_CAP_POINTER)) && + (xwl_ei_client->accept_abs || + !ei_seat_has_capability(xwl_ei_client->ei_seat, EI_DEVICE_CAP_POINTER_ABSOLUTE))) + return true; + + return false; +} + static void xwl_handle_ei_event(int fd, int ready, void *data) { @@ -852,8 +866,10 @@ xwl_handle_ei_event(int fd, int ready, void *data) /* Server has accepted our device (or resumed them), * we can now start sending events */ /* FIXME: Maybe add a timestamp and discard old events? */ - xwl_ei_start_emulating(xwl_ei_client); - xwl_dequeue_emulated_events(xwl_ei_client); + if (xwl_ei_devices_are_ready(xwl_ei_client)) { + xwl_ei_start_emulating(xwl_ei_client); + xwl_dequeue_emulated_events(xwl_ei_client); + } if (!xwl_ei_client->client && xorg_list_is_empty(&xwl_ei_client->pending_emulated_events)) /* All events dequeued and client has disconnected in the meantime */