touch: treat a compositor re-grab down as a drag continuation
Some checks failed
CI / build + test (push) Has been cancelled
CI / cargo audit (push) Has been cancelled

When the surface that owns a touch drag is destroyed mid-gesture, the compositor re-opens the touch grab by issuing a fresh `down` on the surface now under the finger (smithay pins touch focus at `down` and won't re-target on motion). That `down` arrives for a slot the main surface already holds as its primary, with the drag state already migrated here. Handling it through the normal `down` path would either restart the gesture or, since the slot is taken, demote it to an auxiliary touch — both abandon the in-flight drag.
`TouchHandler::down` now early-returns when the focused surface's `primary_touch_id` already equals the incoming slot, so the redundant `down` is a no-op and the following motion/up keep driving the migrated drag. Completes the cross-surface drag fix whose other half (migrating `primary_touch_id` on overlay teardown) already landed.
This commit is contained in:
2026-06-01 00:19:49 +02:00
parent 582f9e1a37
commit 48c5a89712

View File

@@ -58,6 +58,14 @@ impl<A: App> TouchHandler for AppData<A>
let pos = self.surface( focus ).to_physical( position.0, position.1 ); let pos = self.surface( focus ).to_physical( position.0, position.1 );
self.pointer_pos = pos; self.pointer_pos = pos;
// Compositor re-grab after the origin surface died mid-drag: this
// slot is already our primary and the drag state was migrated here,
// so treat the redundant `down` as a continuation, not a restart.
if self.surface( focus ).primary_touch_id == Some( id )
{
return;
}
// Auxiliary slot path: a second (or third…) finger arriving // Auxiliary slot path: a second (or third…) finger arriving
// while another finger already drives the primary slot stays // while another finger already drives the primary slot stays
// out of the single-slot gesture machine entirely. The app // out of the single-slot gesture machine entirely. The app