nixOS/patches/mutter-touch-cancel-forget-sequence.patch
Sergei Poljanski ebc58d2b2a
patches: add traced mutter touch-cancel patches
Two local-test variants for mutter!5375: the NULL-check fix with
g_message traces, and Jonas Ådahl's proposal to forget a cancelled
touch sequence. They log which path cancelled the touch, to answer
how a resize reaches touch_can_grab_surface() with no focus surface.
Not applied yet; desktop.nix still uses mutter-touch-cancelled-grab.

Assisted-by: Claude:opus-5-5
2026-10-20 12:10:06 +04:00

102 lines
3.5 KiB
Diff

From: asxpi <asxpi@narayana.im>
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