From e5ffbb19c0b0ab0544bf42cf4f9b4349b5027204 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= Date: Mon, 3 Apr 2023 15:07:20 +0200 Subject: [PATCH] gdk/wayland: Proivde latest touch serial even after a touch ended When grabbing the seat for an xdg popup using xdg_popup_grab() in response to a touch-end event, we request the grab a little late and the touch is no longer being tracked by gdkseat. This means that _gdk_wayland_seat_get_last_implicit_grab_serial() right now can not provide us with the serial for that touchpoint, because that serial was stored on the GdkWaylandTouchData that is already gone. To still provide the compositor a valid serial in that case, store the serial of the latest touchpoint more persistently in GdkWaylandSeat itself, so that we can still access it when the touchpoint has already ended. --- gdk/wayland/gdkdevice-wayland-private.h | 2 ++ gdk/wayland/gdkseat-wayland.c | 20 +++++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/gdk/wayland/gdkdevice-wayland-private.h b/gdk/wayland/gdkdevice-wayland-private.h index d0dd4433a1..ed45016c73 100644 --- a/gdk/wayland/gdkdevice-wayland-private.h +++ b/gdk/wayland/gdkdevice-wayland-private.h @@ -182,6 +182,8 @@ struct _GdkWaylandSeat GdkWaylandPointerData pointer_info; GdkWaylandPointerData touch_info; + uint32_t latest_touch_down_serial; + GdkModifierType key_modifiers; GdkSurface *keyboard_focus; GdkSurface *grab_surface; diff --git a/gdk/wayland/gdkseat-wayland.c b/gdk/wayland/gdkseat-wayland.c index dcef036ea9..7aad37ffa9 100644 --- a/gdk/wayland/gdkseat-wayland.c +++ b/gdk/wayland/gdkseat-wayland.c @@ -1661,6 +1661,7 @@ touch_handle_down (void *data, touch->x = wl_fixed_to_double (x); touch->y = wl_fixed_to_double (y); touch->touch_down_serial = serial; + seat->latest_touch_down_serial = serial; event = gdk_touch_event_new (GDK_TOUCH_BEGIN, GDK_SLOT_TO_EVENT_SEQUENCE (touch->id), @@ -4363,15 +4364,24 @@ _gdk_wayland_seat_get_last_implicit_grab_serial (GdkWaylandSeat *seat, serial = tablet->pointer_info.press_serial; } - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &touch)) + if (g_hash_table_size (seat->touches) > 0) { - if (touch->touch_down_serial > serial) + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &touch)) { - if (sequence) - *sequence = GDK_SLOT_TO_EVENT_SEQUENCE (touch->id); - serial = touch->touch_down_serial; + if (touch->touch_down_serial > serial) + { + if (sequence) + *sequence = GDK_SLOT_TO_EVENT_SEQUENCE (touch->id); + serial = touch->touch_down_serial; + + } } } + else + { + if (seat->latest_touch_down_serial > serial) + serial = seat->latest_touch_down_serial; + } return serial; }