Make macOS native sizemode transitions asynchronous and uninterruptible
Categories
(Core :: Widget: Cocoa, enhancement, P3)
Tracking
()
Tracking | Status | |
---|---|---|
firefox112 | --- | fixed |
People
(Reporter: xidorn, Assigned: bradwerth)
References
(Depends on 2 open bugs, Blocks 5 open bugs)
Details
(Whiteboard: [mac:fullscreen:native-affected][mac:fullscreen:nonnative-affected][mac:mr1])
Attachments
(4 files, 11 obsolete files)
Per discussion in bug 1563947 comment 1 forward, we can probably try enable full-screen-api.macos-native-full-screen
by default on Nightly to get some feedback before trying to make it better.
I've done a try push: https://treeherder.mozilla.org/#/jobs?repo=try&revision=b2870bb48cbf41d3ceceecac037c28115ba9743a
It seems the fullscreen tests aren't very happy with this, so we need to figure out how can we fix all of them (or disable some if appreciate).
Reporter | ||
Updated•5 years ago
|
Updated•4 years ago
|
Comment 2•4 years ago
|
||
Here's a try push with native fullscreen turned on - full-screen-api.macos-native-full-screen=true
- without any other changes.
Comment 13•4 years ago
|
||
Update: I'm working on getting our tests to pass with native fullscreen enabled.
There are a couple of issues with the current implementation (which is pref’d off). With native fullscreen, we call the nsIWidgetListener callbacks FullscreenWillChange() and FullscreenChanged() from the NSWindow AppKit windowWillEnterFullScreen and windowDidEnterFullScreen callbacks respectively. This is a problem becasue windowWillEnterFullScreen gets called immediately by [NSWindow toggleFullScreen] and windowDidEnterFullScreen is called asynchronously later. This results in the JS fullscreenchange events and promise resolve happening earlier, before Window.fullScreen becomes true. This trips up some tests and is likely to cause webcompat issues so it needs to be fixed. Secondly, if JS attempts to exit fullscreen immediately after getting the fullscreenchange event, this can fail because AppKit ignores the [NSWindow toggleFullScreen] call with no errors apart from a “not in fullscreen state” message logged to the terminal.
I’m working on a fix that calls the listener callbacks FullscreenWillChange() and FullscreenChanged() at the same time like the current non-native implementation. Either they should be called when we first trigger the fullscreen transition and the native transition continues or they are not called until the native transition completes when we receive the windowDidEnterFullScreen callback. Issuing the listener callbacks before the full transition completes is what we do now, but with native it may mean that the fullscreen callbacks fire in JS before the window size reflects the fullscreen change (not confirmed.)
When a new fullscreen request comes in while we are waiting for an existing transition to complete, the fix will maintain the target transition state (fullscreen or normal) and, after a transition completes, start a new transition to the target state.
Comment 14•4 years ago
|
||
Comment 15•4 years ago
|
||
Depends on D114132
Updated•4 years ago
|
Updated•4 years ago
|
Comment 16•4 years ago
|
||
Does not work.
Make fullscreen resize not trigger a resize event.
Depends on D114133
Comment 17•4 years ago
|
||
The posted patch 2 needs some work. Explanation below.
Constraint: when transitioning to fullscreen, the window is resized, but the order of events (fullscreen and resize) should be as follows.
DOM fullscreen triggered by content:
- Window resizes to fullscreen for the native fullscreen animation
- Element.requestFullscreen (or Document.exitFullscreen) promise resolves and the Document.onfullscreenchange event fires and at this time the window dimensions should reflect fullscreen dimensions and the (obsolete) Document.fullscreen property should be set to true. For leaving fullscreen, the window dimensions should reflect the reverted size.
- Window resize event fires
With the existing emulated fullscreen, we resize our window in nsCocoaWindow::DoMakeFullscreen() synchronously. In the same function we call the widget listener methods FullscreenWillChange() and FullscreenChanged().
The resize event comes after entering fullscreen because in nsGlobalWindowOuter::SetWidgetFullscreen() we call nsRefreshDriver::SetIsResizeSuppressed() which delays the resize for one refresh driver tick.
—
When entering native fullscreen the order of callbacks is as follows.
- windowWillEnterFullScreen
- windowDidResize
- windowDidChangeOcclusionState (becomes fully occluded)
- windowDidEnterFullScreen
- windowDidChangeOcclusionState (no longer fully occluded)
For leaving native fullscreen:
- windowWillExitFullScreen
- windowDidResize
- windowDidChangeOcclusionState (becomes fully occluded)
- windowDidExitFullScreen
- windowDidChangeOcclusionState (no longer fully occluded)
The current patch 2 attempts to make the resize in each step 2 take effect such that content is redrawn at the right position, but without delivering a resize event to content until after the fullscreen events are delivered.
The resize in each step 2 draws the window at fullscreen size for the animation.
I’m having trouble making sure the resize events get delivered to content correctly.
Comment 18•4 years ago
|
||
Haik, is patch 2 a fix that will help with issues as reported on bug 1705643?
Comment 19•4 years ago
|
||
(In reply to Henrik Skupin (:whimboo) [⌚️UTC+1] from comment #18)
Haik, is patch 2 a fix that will help with issues as reported on bug 1705643?
For now, I expect the transition will look the same as it does now with full-screen-api.macos-native-full-screen=true
. Specifically, the fade to black and then back out to content will not be used.
Comment 20•4 years ago
|
||
(In reply to Haik Aftandilian [:haik] from comment #17)
I’m having trouble making sure the resize events get delivered to content correctly.
Instead of the approach in patch 2, calling the nsIWidgetListener callbacks from the windowDidResize callback may solve this. Needs more testing.
Comment 23•4 years ago
|
||
(In reply to Haik Aftandilian [:haik] from comment #20)
(In reply to Haik Aftandilian [:haik] from comment #17)
I’m having trouble making sure the resize events get delivered to content correctly.
Instead of the approach in patch 2, calling the nsIWidgetListener callbacks from the windowDidResize callback may solve this. Needs more testing.
This approach didn't work out well. Due to the transition being reported as done in windowDidResize, there is a period of time after this before the NSWindow is fully transitioned and during that time some operations such as starting a new FS transition on another window, trying to close the window, or hide the window don't work and deferring all those operations until after the NSWindow transition fully completes was very complicated.
The think the way forward is to (instead of the approach is patch 2) change windowDidResize to ignore the resize during a DOM FS transition and issue the resize events from windowDidEnterFullScreen instead. However, with that approach I'm running into some focus issues where after coming out of FS leaves the window unfocused that I have not tracked down the root cause of.
Updated•4 years ago
|
Comment 24•4 years ago
|
||
The updated patch finishes the fullscreen transition early in the windowDidResize, but needs more work to properly handling the window being closed while the NSWindow transition is still ongoing.
https://treeherder.mozilla.org/jobs?repo=try&revision=b6b492f30b9d8671e74214a4d604558acccd93c5
Comment 26•3 years ago
|
||
The notch on the new MacBooks raises the priority of landing this.
Comment hidden (off-topic) |
Updated•3 years ago
|
Comment hidden (off-topic) |
Assignee | ||
Comment 35•2 years ago
|
||
This is a rebased version of Haik's logging patch.
Updated•2 years ago
|
Updated•2 years ago
|
Assignee | ||
Comment 36•2 years ago
|
||
This is a rebased version of Haik's logging patch D114132.
Assignee | ||
Comment 37•2 years ago
|
||
This is a rebased version of Haik's patch D114133. It aims to fix the
issues that cause our macOS fullscreen tests to fail.
Depends on D160096
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Comment 38•2 years ago
|
||
Comment on attachment 9299947 [details]
WIP: Bug 1631735 Part 0: Logging of macOS fullscreen methods.
Revision D157015 was moved to bug 1790164. Setting attachment 9299947 [details] to obsolete.
Assignee | ||
Comment 39•2 years ago
|
||
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Assignee | ||
Comment 40•2 years ago
|
||
Haik's original patch seems to work well interactively, both with and without the native fullscreen pref set, but there are still test failures. It's time to get some of this landed. The cleanest way to do this is to land this code without the pref flip, disable some of the failing tests (which seem to run fine in local testing and/or do not reflect problems with interactive fullscreen behavior), and file bugs for both these issues as follow-ups.
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Assignee | ||
Comment 41•2 years ago
|
||
Generally, these tests either run successfully in local automated testing,
or the failures they show are not replicable in interactive testing.
Fixing these tests will be handled in follow-up Bug 1802192.
Depends on D160097
Updated•2 years ago
|
Updated•2 years ago
|
Assignee | ||
Comment 43•2 years ago
|
||
fullscreen tests
Since macOS fullscreen can handle incoming fullscreen requests during a
fullscreen transition, it is no longer necessary to check for
visibilitychange events, which are also no longer fired.
Depends on D160097
Assignee | ||
Comment 44•2 years ago
|
||
Depends on D164247
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Assignee | ||
Comment 45•2 years ago
|
||
Depends on D164248
Updated•2 years ago
|
Updated•2 years ago
|
Comment 46•2 years ago
|
||
Comment 47•2 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/fe09769d7d5a
https://hg.mozilla.org/mozilla-central/rev/4b8cc0917731
https://hg.mozilla.org/mozilla-central/rev/a6d345a47718
https://hg.mozilla.org/mozilla-central/rev/781c1031c032
Comment 48•2 years ago
|
||
Backed out for causing bug 1806355
Backout link: https://hg.mozilla.org/integration/autoland/rev/08ef61194a1e6d5022afb99c2ead79e0ed712eb9
Comment 49•2 years ago
|
||
Sandor, with the backout of this patch we should also backout the patch from 1806262 which otherwise would cause test failures.
Comment 50•2 years ago
•
|
||
@whimboo, already did that. had to because it caused conflict when backing out
Comment 51•2 years ago
|
||
When these patches land again, they should probably land in a different bug, because these patches don't change the pref default so they don't fix this bug.
Comment 52•2 years ago
|
||
Backout merged to central: https://hg.mozilla.org/mozilla-central/rev/08ef61194a1e6d5022afb99c2ead79e0ed712eb9
Comment 54•2 years ago
|
||
When these patches land again, we should land them in a different bug because they don't actually flip the default and, on their own, don't fix the bugs we've been duping against this one.
Updated•2 years ago
|
Assignee | ||
Comment 55•2 years ago
|
||
I'm revising this to have a more general queue of pending transitions (fullscreen, minimize, hide, etc.)
Updated•2 years ago
|
Updated•2 years ago
|
Assignee | ||
Comment 56•2 years ago
|
||
This patch attempts to make nsCocoaWindow transitions (fullscreen,
windowed, minimize, zoom) atomic operations that can't be disrupted by
user action or by programmatic triggers. To accomplish this, it defines a
transition queue which ensures that when a transition is submitted, it is
always run to completion before another transition is started.
Additionally, it will add additional transitions in to handle programmatic
requests which aren't allowed by macOS, which include:
- Attempting to minimize a fullscreen window will first transition to
windowed state. - Any operation on a minimized window will first transition to windowed
state.
Since some of these transitions are animated, this patch also makes clear
when the size mode event is sent for each type of transition:
Enter or exit fullscreen: beginning of animation.
Minimize or Deminimize: end of animation.
Enter or Zoom: end of transition, which is not animated.
This matches existing test expectations, with the exception of a few tests
which assume that window.minimize is synchronous. In all cases, the next
transition must wait for the previous transition (including any animation) to
complete.
Assignee | ||
Comment 57•2 years ago
|
||
Depends on D166450
Assignee | ||
Updated•2 years ago
|
Updated•2 years ago
|
Assignee | ||
Updated•2 years ago
|
Assignee | ||
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Assignee | ||
Comment 58•2 years ago
|
||
Depends on D164248
Assignee | ||
Comment 59•2 years ago
|
||
Per review feedback, we'll make the native sizemode transitions asynchronous (fullscreen, minimize) and the other transitions synchronous (normal/windowed, maximized/zoom).
Comment 60•2 years ago
|
||
Comment 61•2 years ago
|
||
Backed out for causing bc assertion failures in xpfe/appshell/AppWindow.cpp
Backout link: https://hg.mozilla.org/integration/autoland/rev/c0fa92102e0a51f82c04fdc3f3008cb2b5a55747
Assignee | ||
Comment 62•2 years ago
|
||
Hmm... I had thought that the new test browser_fullscreen_from_minimize.js
would cleanly fail on Windows, but since it fails with an assert, it'll need to be skipped instead.
Assignee | ||
Comment 63•2 years ago
|
||
There's a second problem in Part 1 where an inserted transition that is asynchronous will not correctly break out of the ProcessTransitions
function, because there's still another transition in the queue. That needs a fix.
Assignee | ||
Comment 64•2 years ago
|
||
(In reply to Brad Werth [:bradwerth] from comment #63)
There's a second problem in Part 1 where an inserted transition that is asynchronous will not correctly break out of the
ProcessTransitions
function, because there's still another transition in the queue. That needs a fix.
Actually, that looks fine, but an inserted transition to windowed mode may send an unwanted sizemodechange event if the window is currently in emulated fullscreen. I'll put a patch together.
Assignee | ||
Comment 65•2 years ago
|
||
Depends on D170841
Comment 66•2 years ago
|
||
Comment 67•2 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/c9995ff92253
https://hg.mozilla.org/mozilla-central/rev/98df31ea18e2
https://hg.mozilla.org/mozilla-central/rev/8201fa6c6156
https://hg.mozilla.org/mozilla-central/rev/168ec9dca708
Updated•2 years ago
|
Description
•