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.
This commit is contained in:
Jonas Dreßler
2023-04-03 15:07:20 +02:00
parent 79b0e594cd
commit e5ffbb19c0
2 changed files with 17 additions and 5 deletions

View File

@@ -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;

View File

@@ -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;
}