moveHandler: Remove the monitor grace period timer when a grab ends - #461
Open
PhilMeyr wants to merge 1 commit into
Open
moveHandler: Remove the monitor grace period timer when a grab ends#461PhilMeyr wants to merge 1 commit into
PhilMeyr wants to merge 1 commit into
Conversation
When a drag crosses a monitor boundary, _edgeTilingPreview() arms a 150 ms timer that captures the dragged window and re-enters _edgeTilingPreview() when it fires. Nothing removes that source when the grab ends, so a window destroyed within those 150 ms leaves it pending. It then reaches window.get_work_area_for_monitor(), which asserts in meta_window_get_workspaces() on an unmanaging window and aborts the shell. Remove the pending source in the finally block of _onMoveFinished(), and guard the callback with get_compositor_private(), since is_grabbed() is a property of the display rather than of the window. Closes ubuntu#435
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the GNOME Shell abort reported in #435, which several of us have hit on Ubuntu 26.04 (@YannickMG, @cpaelzer and myself, plus the original report on Debian 13 / GNOME 48).
The bug
_edgeTilingPreview()arms a 150 ms grace period timer when a drag crosses a monitor boundary, so the tile preview sticks to the previous monitor for a moment:The callback captures
window, but the source is only ever removed indestroy()— never when the grab it belongs to ends._onMoveFinished()'sfinallyblock tears down everything else (_posChangedId, the tile preview,_isGrabOp) and leaves this one pending.So if the dragged window is destroyed within those 150 ms — tearing off or dropping a browser tab does exactly that — the orphaned timer still fires and re-enters
_edgeTilingPreview(), reaching:meta_window_get_work_area_for_monitor()→meta_window_get_workspaces()→g_assert_not_reached()on an unmanaging window →SIGABRT. Being a C assertion, no JS guard can contain it, and the whole Wayland session dies.The
unmanagingJS error logged from_onMoveFinished()in every report is a separate, non-fatal event that merely signals the window is gone. In my logs the two are consistently ~140 ms apart, and on 2026-07-28 that error occurred with no abort at all — the session survived two more days.The fix
finallyblock of_onMoveFinished(), so it cannot outlive the operation that armed it. This is what actually fixes the crash.window.get_compositor_private().global.display.is_grabbed()is a property of the display and says nothing about this window still being managed; the same idiom is already used infocusHint.js:290.Notes
monitor-switch-grace-period falseworks as a user-side workaround on released versions.if (this._lastMonitorNr !== currMonitorNr), which matches every report in Wayland crash report #435 being multi-monitor.finallycleanup and drop the second guard.