[Wayland] Minimizing a window never sets nsSizeMode_Minimized, so sizemodechange never fires and the docshell stays active
Categories
(Core :: Widget: Gtk, defect)
Tracking
()
People
(Reporter: dao, Unassigned)
References
(Depends on 1 open bug, Blocks 2 open bugs)
Details
Attachments
(1 obsolete file)
On Wayland, nsWindow::SetSizeMode(nsSizeMode_Minimized) calls gtk_window_iconify(), but GTK does not synthesize a window-state-event carrying GDK_WINDOW_STATE_ICONIFIED (upstream https://gitlab.gnome.org/GNOME/gtk/-/issues/67, already noted in a comment in nsWindow::OnWindowStateEvent). mSizeMode therefore never becomes nsSizeMode_Minimized and nsIWidgetListener::SizeModeChanged is never called.
Everything downstream of AppWindow::SizeModeChanged is then skipped: no sizemodechange event, and RecomputeBrowsingContextVisibility() never runs, so CanonicalBrowsingContext::RecomputeAppWindowVisibility keeps the window active - it decides from widget->SizeMode() != nsSizeMode_Minimized and IsFullyOccluded(), and GTK occlusion is X11-only (nsWindow::OnVisibilityNotifyEvent). So for a minimized window on Wayland, docShellIsActive stays true, document.hidden stays false, visibilitychange never fires, and PauseOrResumeCompositor is never called. Painting appears to stop only incidentally, because frame callbacks stop driving vsync (cf. bug 1854920).
nsWindow already compensates in the restore direction - the waylandWasIconified heuristic in OnWindowStateEvent infers un-minimize from regaining focus while mSizeMode == nsSizeMode_Minimized - but on Wayland nothing ever sets that state to begin with.
Steps to reproduce: in a Wayland session, load a page that logs visibilitychange and reads document.hidden, then minimize the window.
Expected: sizemodechange fires on the chrome window, document.hidden becomes true.
Actual: neither happens. (Derived from code analysis; the missing sizemodechange is confirmed by the test failure in bug 2057865.)
Possible fixes: treat the minimize request as effective on Wayland by setting mSizeMode and notifying the listener when gtk_window_iconify() is called, mirroring the existing restore-side heuristic. That is optimistic, since xdg-shell has no acknowledgment for xdg_toplevel.set_minimized and the state would be wrong if the compositor ignored the request. Longer term, use the suspended toplevel state (xdg-shell v6, XDG_TOPLEVEL_STATE_SUSPENDED in widget/gtk/wayland/xdg-shell-client-protocol.h), which GDK3 does not expose but GTK4 does as GDK_TOPLEVEL_STATE_SUSPENDED.
Test impact: browser_lastSeenActive.js is disabled on Linux Wayland because of this (bug 2057865) - its switchingWindows task waits for sizemodechange after win.minimize() and times out.
https://tests.firefox.dev/test.html?test=browser%2Fcomponents%2Ftabbrowser%2Ftest%2Fbrowser%2Ftabs%2Fbrowser_lastSeenActive.js
| Reporter | ||
Updated•9 days ago
|
| Reporter | ||
Updated•8 days ago
|
| Reporter | ||
Comment 1•8 days ago
|
||
Wayland has no equivalent of GDK_WINDOW_STATE_ICONIFIED and xdg-shell doesn't
acknowledge xdg_toplevel.set_minimized, so nothing ever moved a window into
nsSizeMode_Minimized there: sizemodechange never fired, the docshell stayed
active and document.hidden stayed false for a minimized window. The request
itself is the only signal available, so take it at face value.
That makes the existing restore heuristic reachable for the first time, so the
state now has to survive until focus comes back: with ICONIFIED never set, its
absence in a state event carrying unrelated changes would read as a restore.
Minimizing being observable again is what the guard below this commit stood in
for, so browser_lastSeenActive.js goes back to covering it everywhere.
Worth knowing while reviewing: a focus-in already in flight when the request is
made is still mistaken for a restore, which browser_BrowserWindowTracker_-
minimize.js hits intermittently. That test also waits on restoring a minimized
window, which is bug 1923833, so it stays skipped on Wayland.
Updated•8 days ago
|
Comment 2•8 days ago
|
||
Bug 2057856 is probably affected in a similar way. It is performing a direct maximized -> minimized transition that may have additional complications, though.
Comment 3•8 days ago
|
||
Bug 2057858 (https://searchfox.org/firefox-main/source/browser/components/sessionstore/test/browser_524745.js) — calls window_B.minimize() and window.minimize(), waiting on sizemodechange.
Updated•8 days ago
|
| Reporter | ||
Comment 4•8 days ago
|
||
Got push back on the patch; it seems that this can't be fixed cleanly under GTK3 and will have to wait for a proper GTK4 implementation.
| Reporter | ||
Updated•8 days ago
|
| Reporter | ||
Comment 5•7 days ago
|
||
I guess let's keep this open as a status tracker and reference point.
| Reporter | ||
Updated•7 days ago
|
Comment 6•7 days ago
|
||
FWIW gtk4 also won't fix this. There's just no guaranteed way to know you're really minimized on wayland. Note also that the docshell doesn't always stay active, compositors have ways to throttle us and we end up disabling the refresh driver for those via the window occlusion mechanism.
Updated•3 days ago
|
Description
•