diff --git a/patches/mutter-touch-cancel-forget-sequence.patch b/patches/mutter-touch-cancel-forget-sequence.patch new file mode 100644 index 0000000..4aabede --- /dev/null +++ b/patches/mutter-touch-cancel-forget-sequence.patch @@ -0,0 +1,102 @@ +From: asxpi +Subject: [PATCH] wayland/touch: Forget a touch point once it is cancelled + +Jonas Ã…dahl's proposal on mutter!5375 (note 2904581), completed so it +builds: meta_wayland_touch_cancel() takes the event, and on +CLUTTER_TOUCH_CANCEL the cancelled sequence leaves touch->touches, so no +stale MetaWaylandTouchInfo (focus_surface NULL, slot_serial still set) +is left for touch_can_grab_surface() to find. The other callers cancel +every touch and have no event; they pass NULL and keep today's +behaviour. + +LOCAL TEST ONLY: the g_message says which path cancelled, to tell +whether the Tauri double xdg_toplevel.resize goes through +CLUTTER_TOUCH_CANCEL or through the seat's focus change. + +Upstream: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/5375#note_2904581 +--- +--- a/src/wayland/meta-wayland-touch.c ++++ b/src/wayland/meta-wayland-touch.c +@@ -524,7 +524,7 @@ + break; + + case CLUTTER_TOUCH_CANCEL: +- meta_wayland_touch_cancel (touch); ++ meta_wayland_touch_cancel (touch, event); + break; + + default: +@@ -561,7 +561,8 @@ + } + + void +-meta_wayland_touch_cancel (MetaWaylandTouch *touch) ++meta_wayland_touch_cancel (MetaWaylandTouch *touch, ++ const ClutterEvent *event) + { + MetaWaylandInputDevice *input_device = META_WAYLAND_INPUT_DEVICE (touch); + MetaWaylandSeat *seat = meta_wayland_input_device_get_seat (input_device); +@@ -572,6 +573,9 @@ + if (!meta_wayland_seat_has_touch (seat)) + return; + ++ g_message ("touch cancel via %s", ++ event ? "CLUTTER_TOUCH_CANCEL" : "focus change or disable"); ++ + surfaces = s = touch_get_surfaces (touch, FALSE); + + for (s = surfaces; s; s = s->next) +@@ -589,6 +593,10 @@ + while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &touch_info)) + g_clear_pointer (&touch_info->focus_surface, touch_surface_decrement_touch); + g_list_free (surfaces); ++ ++ if (event) ++ g_hash_table_remove (touch->touches, ++ clutter_event_get_event_sequence (event)); + } + + void +@@ -607,7 +615,7 @@ + void + meta_wayland_touch_disable (MetaWaylandTouch *touch) + { +- meta_wayland_touch_cancel (touch); ++ meta_wayland_touch_cancel (touch, NULL); + + g_clear_pointer (&touch->touches, g_hash_table_unref); + g_clear_pointer (&touch->touch_surfaces, g_hash_table_unref); +--- a/src/wayland/meta-wayland-touch.h ++++ b/src/wayland/meta-wayland-touch.h +@@ -61,7 +61,8 @@ + struct wl_client *client, + struct wl_resource *seat_resource, + uint32_t id); +-void meta_wayland_touch_cancel (MetaWaylandTouch *touch); ++void meta_wayland_touch_cancel (MetaWaylandTouch *touch, ++ const ClutterEvent *event); + + + ClutterEventSequence * meta_wayland_touch_find_grab_sequence (MetaWaylandTouch *touch, +--- a/src/wayland/meta-wayland-seat.c ++++ b/src/wayland/meta-wayland-seat.c +@@ -259,7 +259,7 @@ + sequence = clutter_sprite_get_sequence (CLUTTER_SPRITE (focus)); + + if (surface != meta_wayland_touch_get_focus_surface (seat->touch, sequence)) +- meta_wayland_touch_cancel (seat->touch); ++ meta_wayland_touch_cancel (seat->touch, NULL); + + break; + } +--- a/src/core/display.c ++++ b/src/core/display.c +@@ -608,7 +608,7 @@ + MetaWaylandCompositor *compositor; + + compositor = wayland_compositor_from_display (display); +- meta_wayland_touch_cancel (compositor->seat->touch); ++ meta_wayland_touch_cancel (compositor->seat->touch, NULL); + } + + static void diff --git a/patches/mutter-touch-cancel-trace.patch b/patches/mutter-touch-cancel-trace.patch new file mode 100644 index 0000000..fa2b2c1 --- /dev/null +++ b/patches/mutter-touch-cancel-trace.patch @@ -0,0 +1,54 @@ +From: asxpi +Subject: [PATCH] wayland/touch: Don't crash on grab requests for cancelled touches (traced) + +The same NULL check as mutter-touch-cancelled-grab.patch (mutter!5375): +a touch cancelled while the finger is still down keeps its +MetaWaylandTouchInfo with focus_surface NULL (deliberately, since !5057), +and a grab request with its serial must be refused rather than crash in +touch_can_grab_surface(). + +LOCAL TEST ONLY: three g_message lines say which path cancelled the touch +(CLUTTER_TOUCH_CANCEL or the seat's focus change) and when a grab for a +cancelled touch was refused, to answer the open question on !5375 of how a +resize reaches touch_can_grab_surface() with no focus surface. + +Upstream: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/5375 +--- +--- a/src/wayland/meta-wayland-touch.c ++++ b/src/wayland/meta-wayland-touch.c +@@ -524,6 +524,7 @@ + break; + + case CLUTTER_TOUCH_CANCEL: ++ g_message ("touch-trace: cancel via CLUTTER_TOUCH_CANCEL"); + meta_wayland_touch_cancel (touch); + break; + +@@ -656,6 +657,13 @@ + { + MetaWaylandSurface *subsurface; + ++ /* Cleared by meta_wayland_touch_cancel() while the touch is still down */ ++ if (!touch_info->focus_surface) ++ { ++ g_message ("touch-trace: grab refused for a cancelled touch"); ++ return FALSE; ++ } ++ + if (touch_info->focus_surface->surface == surface) + return TRUE; + +--- a/src/wayland/meta-wayland-seat.c ++++ b/src/wayland/meta-wayland-seat.c +@@ -259,7 +259,10 @@ + sequence = clutter_sprite_get_sequence (CLUTTER_SPRITE (focus)); + + if (surface != meta_wayland_touch_get_focus_surface (seat->touch, sequence)) +- meta_wayland_touch_cancel (seat->touch); ++ { ++ g_message ("touch-trace: cancel via seat focus change"); ++ meta_wayland_touch_cancel (seat->touch); ++ } + + break; + }