Bug 1826645 Part 2: Make Document hold fullscreen requests while an exit is being processed. r=edgar

This change makes the parent process delay a fullscreen request if there
is a pending fullscreen exit. It also changes the DOMFullscreenParent
actor listener lifecycle. Once it has started handling a fullscreen
request, it will remain a listener to the Document until it receives an
exit event when the manager is out of fullscreen.

Differential Revision: https://phabricator.services.mozilla.com/D175186
This commit is contained in:
Brad Werth 2023-04-18 16:10:03 +00:00
parent 18b4b5fd3f
commit 80e8eb7818
3 changed files with 33 additions and 24 deletions

View file

@ -239,7 +239,12 @@ export class DOMFullscreenParent extends JSWindowActorParent {
}
this.cleanupDomFullscreen(window);
this.updateFullscreenWindowReference(window);
this.removeListeners(window);
// If the document is supposed to be in fullscreen, keep the listener to wait for
// further events.
if (!this.manager.fullscreen) {
this.removeListeners(window);
}
break;
}
}

View file

@ -14467,10 +14467,13 @@ class ExitFullscreenScriptRunnable : public Runnable {
nsContentUtils::DispatchEventOnlyToChrome(
mLeaf, ToSupports(mLeaf), u"MozDOMFullscreen:Exited"_ns,
CanBubble::eYes, Cancelable::eNo, /* DefaultAction */ nullptr);
// Ensure the window exits fullscreen.
// Ensure the window exits fullscreen, as long as we don't have
// pending fullscreen requests.
if (nsPIDOMWindowOuter* win = mRoot->GetWindow()) {
win->SetFullscreenInternal(FullscreenReason::ForForceExitFullscreen,
false);
if (!mRoot->HasPendingFullscreenRequests()) {
win->SetFullscreenInternal(FullscreenReason::ForForceExitFullscreen,
false);
}
}
return NS_OK;
}
@ -15262,6 +15265,15 @@ static bool ShouldApplyFullscreenDirectly(Document* aDoc,
if (!iter.AtEnd()) {
return false;
}
// Same thing for exits. If we have any pending, we have to push
// to the pending queue.
PendingFullscreenChangeList::Iterator<FullscreenExit> iterExit(
aDoc, PendingFullscreenChangeList::eDocumentsWithSameRoot);
if (!iterExit.AtEnd()) {
return false;
}
// We have to apply the fullscreen state directly in this case,
// because nsGlobalWindow::SetFullscreenInternal() will do nothing
// if it is already in fullscreen. If we do not apply the state but
@ -15341,6 +15353,15 @@ void Document::RequestFullscreenInParentProcess(
return;
}
// See if we're waiting on an exit. If so, just make this one pending.
PendingFullscreenChangeList::Iterator<FullscreenExit> iter(
this, PendingFullscreenChangeList::eDocumentsWithSameRoot);
if (!iter.AtEnd()) {
PendingFullscreenChangeList::Add(std::move(aRequest));
rootWin->SetFullscreenInternal(FullscreenReason::ForFullscreenAPI, true);
return;
}
// We don't need to check element ready before this point, because
// if we called ApplyFullscreen, it would check that for us.
if (!FullscreenElementReadyCheck(*aRequest)) {

View file

@ -1977,8 +1977,8 @@ nsresult AppWindow::SetPersistentValue(const nsAtom* aAttr,
void AppWindow::MaybeSavePersistentPositionAndSize(
PersistentAttributes aAttributes, Element& aRootElement,
const nsAString& aPersistString, bool aShouldPersist) {
if ((aAttributes & PersistentAttributes{PersistentAttribute::Position,
PersistentAttribute::Size})
if ((aAttributes& PersistentAttributes{PersistentAttribute::Position,
PersistentAttribute::Size})
.isEmpty()) {
return;
}
@ -2915,24 +2915,7 @@ void AppWindow::SizeModeChanged(nsSizeMode aSizeMode) {
nsCOMPtr<nsPIDOMWindowOuter> ourWindow =
mDocShell ? mDocShell->GetWindow() : nullptr;
if (ourWindow) {
// Ensure that the fullscreen state is synchronized between
// the widget and the outer window object.
if (aSizeMode != nsSizeMode_Fullscreen &&
aSizeMode != nsSizeMode_Minimized) {
if (ourWindow->GetFullScreen()) {
// The first SetFullscreenInternal call below ensures that we do
// not trigger any fullscreen transition even if the window was
// put in fullscreen only for the Fullscreen API. The second
// SetFullScreen call ensures that the window really exit from
// fullscreen even if it entered fullscreen for both Fullscreen
// Mode and Fullscreen API.
ourWindow->SetFullscreenInternal(
FullscreenReason::ForForceExitFullscreen, false);
ourWindow->SetFullScreen(false);
}
}
// And always fire a user-defined sizemodechange event on the window
// Always fire a user-defined sizemodechange event on the window
ourWindow->DispatchCustomEvent(u"sizemodechange"_ns);
}