Files
kitty/glfw/wl_platform.h
ttyS3 98366076e1 fix(wayland): detect start_drag silently ignored by the compositor
The pointer_button_count check added in dc36e2165 uses the client side
view of the implicit grab, which is stale when the button release is
still in flight: glfwStartDrag passes the check, but by the time the
compositor processes wl_data_device.start_drag the implicit grab is
gone and the request is silently dropped. The data source then never
receives any event, so the tab drag state leaks forever, hijacking
mouse handling again, and the already created xdg_toplevel_drag
toplevel gets mapped as a stray undecorated window showing the drag
thumbnail that nothing ever destroys.

Detect this deterministically using protocol ordering: issue a
wl_display.sync right after start_drag. An accepted start_drag
synchronously produces events (wl_pointer.leave from the DND grab
taking over, wl_data_device.enter, wl_data_source events) that are
ordered before the sync callback. If the callback fires with none of
them seen, the request was dropped: cancel the drag, which notifies
the application (clearing the tab drag state) and destroys the drag
toplevel and data source.

Also defer mapping the drag toplevel until the session is confirmed,
so the stray window can never appear, not even for one frame.

Verified against headless GNOME Shell 50.2 (mutter) with injected
pointer timing scans: the unpatched build deadlocks with an orphaned
drag toplevel within ~13 fast flicks, the patched build catches every
race hit and cancels cleanly, with no deadlock, no stray window, and
normal slow drag/reorder/detach behaviour preserved.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-12 14:16:22 +08:00

19 KiB
Vendored