Open Bug 2040447 Opened 1 month ago Updated 22 days ago

Closing multiple windows from dock intermittently does not display signout prompt

Categories

(Enterprise Products :: Firefox, defect, P1)

Desktop
Linux

Tracking

(Not tracked)

People

(Reporter: jporter, Assigned: jporter)

References

(Depends on 2 open bugs)

Details

Video: https://bugzilla.mozilla.org/show_bug.cgi?id=2035796#c1

This is an extension of bug 2035796 which contained a second video of a semi-related bug to the original scenario, where clicking "Quit X Windows" from the OS dock icon closes each window separately, rather than sending a quit-application-requested signal, resulting in a race condition when the topmost window has a "heavy" page loaded.

Affected Platforms
Windows and Linux. MacOS sends a single quit-application-requested signal and is unaffected.

Preconditions

  • Have multiple FxE windows open
  • Open at least one "heavy" site in a new tab on the topmost window
  • enterprise.prompt_on_signout is set to true
  • browser.tabs.warnOnClose is set to false

Steps to reproduce

  1. From the menu bar, right click and select Quit x windows

Expected result
The signout dialog is displayed on the last window to close.

Actual result
The signout dialog is not displayed at all and all the windows are just closed.

This is also reproducible by opening the "heavy" site in the first window, opening a new window, then bringing the heavy one to the foreground. This seems to be a race when the OS window manager dispatches a quit signal to all windows in Z order, and the topmost window takes slightly longer to complete closing.

This results in both windows racing through their exit sequence and detecting another window open, so it never thinks it's the "last window to close" which is the scenario in which we display our custom dialog.

In normal Firefox this race usually isn't visible because browser.tabs.warnOnClose also drives a per-window "Close N tabs?" warning from warnAboutClosingWindow that runs independently of the last-window check. With multi-tab windows you always see that per-window prompt, so the cross-window quit prompt being lost to the race goes unnoticed. With one tab per window the per-window warning stays silent and the cross-window prompt disappears too, which is the same quit-application-requested path our Enterprise dialog hooks into.

Some more details on this. Added some logging to help debug the browser close process, and it does seem like the heavier page being in the topmost window triggers the race.

1779148602712 [ENT-RACE] WindowIsClosing ENTER winId=29 title=Slack | AI Work Platform & Productivity Tools  Firefox Enterprise source=OS
1779148602712 [ENT-RACE] closeWindow ENTER winId=29 aClose=false aSource=OS self.title=Slack | AI Work Platform & Productivity Tools  Firefox Enterprise windowCount=2 wins=[{"id":1,"closed":false,"title":"Firefox Enterprise"},{"id":29,"closed":false,"title":"Slack | AI Work Platform & Productivity Tools  Firefox Enterprise"}]
1779148602725 [ENT-RACE] closeWindow PROCEEDING winId=29 (took warn-tabs branch)
1779148602728 [ENT-RACE] WindowIsClosing ENTER winId=1 title=Firefox Enterprise source=OS
1779148602729 [ENT-RACE] closeWindow ENTER winId=1 aClose=false aSource=OS self.title=Firefox Enterprise windowCount=2 wins=[{"id":1,"closed":false,"title":"Firefox Enterprise"},{"id":29,"closed":false,"title":"Slack | AI Work Platform & Productivity Tools  Firefox Enterprise"}]
1779148602730 [ENT-RACE] closeWindow PROCEEDING winId=1 (took warn-tabs branch)
1779148602730 [ENT-RACE] WindowIsClosing RETURN true winId=1 (CanCloseWindow ok)
1779148602754 [ENT-RACE] WindowIsClosing RETURN true winId=29 (CanCloseWindow ok)

The top window containing slack.com (winId=29) starts closing first, but then while it's stuck waiting on permitUnload (the 13ms gap between PROCEEDING and RETURN), the other window (winId=1) kicks off and runs its whole close in 2ms. Both windows look at the window list during this, and since neither is fully closed yet, they both see 2 open windows and skip the "last window" check, which is the only thing that triggers the enterprise prompt. Then they both return, and Firefox just exits each window like a normal close.

Did some more digging and found some semi-related bugs for additional context:

Bug 1818971: this one relates more to bug 2035796, but trigger of this bug is the same issue where each window gets a WM_CLOSE and most windows are torn down without the "last window" logic branch due to a race condition
Bug 1858782: same as above, different symptom of the simultaneous window closing issue

Based on these discussions, it seems that our Enterprise Signout prompt not showing in some scenarios when multiple windows are closed is a manifestation of the same long-standing m-c issue. Each window gets a WM_CLOSE, and the per-window "am I the last?" check in toolkit/content/globalOverlay.js is racy because .closed doesn't flip until after the handler returns, while CanCloseWindow -> browser.permitUnload() continues processing events during its sync IPC and lets the next window's WM_CLOSE handler dispatch and run to completion before the first window's handler returns.

Depends on: 2048223
You need to log in before you can comment on or make changes to this bug.