tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 346191b515c9a661a28b2bed90a32f22bac56d63
parent 905203a35fbfd65816697064676b37bc80d060fb
Author: Vincent Hilla <vhilla@mozilla.com>
Date:   Mon, 29 Dec 2025 08:34:56 +0000

Bug 2002767 - Show initial about:blank as soon as possible after start-up. r=smaug,firefox-desktop-core-reviewers ,Gijs

To improve perceived performance, bug 1336227 showed a blank window early after
start-up. Bug 543435 (sync-about-blank) broke this because the navigation for
the initial about:blank cannot be stopped. win.stop() wouldn't cause a state
stop and to prevent the completing load from breaking other code, we loaded
nothing at all.
This commit introduces a more explicit method to show the initial document.

Differential Revision: https://phabricator.services.mozilla.com/D277151

Diffstat:
Mbrowser/components/BrowserGlue.sys.mjs | 11++++++-----
Mxpfe/appshell/AppWindow.cpp | 101+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Mxpfe/appshell/nsIAppWindow.idl | 7+++++++
3 files changed, 70 insertions(+), 49 deletions(-)

diff --git a/browser/components/BrowserGlue.sys.mjs b/browser/components/BrowserGlue.sys.mjs @@ -698,6 +698,10 @@ BrowserGlue.prototype = { docElt.setAttribute("screenX", getValue("screenX")); docElt.setAttribute("screenY", getValue("screenY")); + let appWin = win.docShell.treeOwner + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIAppWindow); + // The sizemode="maximized" attribute needs to be set before first paint. let sizemode = getValue("sizemode"); let width = getValue("width") || 500; @@ -708,9 +712,6 @@ BrowserGlue.prototype = { // Set the size to use when the user leaves the maximized mode. // The persisted size is the outer size, but the height/width // attributes set the inner size. - let appWin = win.docShell.treeOwner - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIAppWindow); height -= appWin.outerToInnerHeightDifferenceInCSSPixels; width -= appWin.outerToInnerWidthDifferenceInCSSPixels; docElt.setAttribute("height", height); @@ -725,8 +726,8 @@ BrowserGlue.prototype = { // decide to skip some expensive code paths (eg. starting the GPU process). docElt.setAttribute("windowtype", "navigator:blank"); - // The window becomes visible after OnStopRequest, so make this happen now. - win.stop(); + // Show a blank window as soon as possible after start-up + appWin.showInitialViewer(); ChromeUtils.addProfilerMarker("earlyBlankFirstPaint", startTime); win.openTime = ChromeUtils.now(); diff --git a/xpfe/appshell/AppWindow.cpp b/xpfe/appshell/AppWindow.cpp @@ -1082,31 +1082,6 @@ NS_IMETHODIMP AppWindow::ForceRoundedDimensions() { return NS_OK; } -void AppWindow::OnChromeLoaded() { - nsresult rv = EnsureContentTreeOwner(); - - if (NS_SUCCEEDED(rv)) { - mChromeLoaded = true; - ApplyChromeFlags(); - SyncAttributesToWidget(); - if (RefPtr ps = GetPresShell()) { - // Sync window properties now, before showing the window. - ps->SyncWindowPropertiesIfNeeded(); - } - if (mWindow) { - SizeShell(); - if (mShowAfterLoad) { - SetVisibility(true); - } - AddTooltipSupport(); - } - // At this point the window may have been closed already during Show() or - // SyncAttributesToWidget(), so AppWindow::Destroy may already have been - // called. Take care! - } - mPersistentAttributesMask += AllPersistentAttributes(); -} - bool AppWindow::NeedsTooltipListener() { nsCOMPtr<dom::Element> docShellElement = GetWindowDOMElement(); if (!docShellElement || docShellElement->IsXULElement()) { @@ -3035,6 +3010,63 @@ void AppWindow::PersistentAttributesDirty(PersistentAttributes aAttributes, void AppWindow::FirePersistenceTimer() { SavePersistentAttributes(); } +void AppWindow::OnChromeLoaded() { + MOZ_ASSERT(!mChromeLoaded); + + mChromeLoaded = true; + mLockedUntilChromeLoad = false; + +#ifdef USE_NATIVE_MENUS + /////////////////////////////// + // Find the Menubar DOM and Load the menus, hooking them up to the loaded + // commands + /////////////////////////////// + if (!gfxPlatform::IsHeadless()) { + if (RefPtr<Document> menubarDoc = mDocShell->GetExtantDocument()) { + if (mIsHiddenWindow || !sWaitingForHiddenWindowToLoadNativeMenus) { + BeginLoadNativeMenus(menubarDoc, mWindow); + } else { + sLoadNativeMenusListeners.EmplaceBack(menubarDoc, mWindow); + } + } + } +#endif // USE_NATIVE_MENUS + + nsresult rv = EnsureContentTreeOwner(); + + if (NS_SUCCEEDED(rv)) { + ApplyChromeFlags(); + SyncAttributesToWidget(); + if (RefPtr ps = GetPresShell()) { + // Sync window properties now, before showing the window. + ps->SyncWindowPropertiesIfNeeded(); + } + if (mWindow) { + SizeShell(); + if (mShowAfterLoad) { + SetVisibility(true); + } + AddTooltipSupport(); + } + // At this point the window may have been closed already during Show() or + // SyncAttributesToWidget(), so AppWindow::Destroy may already have been + // called. Take care! + } + mPersistentAttributesMask += AllPersistentAttributes(); +} + +NS_IMETHODIMP +AppWindow::ShowInitialViewer() { + NS_ENSURE_FALSE(mChromeLoaded, NS_ERROR_UNEXPECTED); + + MOZ_ASSERT(mDocShell->GetDocument()->IsUncommittedInitialDocument(), + "This method is for showing the initial document, not the result " + "of a some navigation"); + + OnChromeLoaded(); + return NS_OK; +} + //---------------------------------------- // nsIWebProgessListener implementation //---------------------------------------- @@ -3068,25 +3100,6 @@ AppWindow::OnStateChange(nsIWebProgress* aProgress, nsIRequest* aRequest, if (eventPWin != rootPWin) return NS_OK; } - mChromeLoaded = true; - mLockedUntilChromeLoad = false; - -#ifdef USE_NATIVE_MENUS - /////////////////////////////// - // Find the Menubar DOM and Load the menus, hooking them up to the loaded - // commands - /////////////////////////////// - if (!gfxPlatform::IsHeadless()) { - if (RefPtr<Document> menubarDoc = mDocShell->GetExtantDocument()) { - if (mIsHiddenWindow || !sWaitingForHiddenWindowToLoadNativeMenus) { - BeginLoadNativeMenus(menubarDoc, mWindow); - } else { - sLoadNativeMenusListeners.EmplaceBack(menubarDoc, mWindow); - } - } - } -#endif // USE_NATIVE_MENUS - OnChromeLoaded(); return NS_OK; diff --git a/xpfe/appshell/nsIAppWindow.idl b/xpfe/appshell/nsIAppWindow.idl @@ -151,4 +151,11 @@ interface nsIAppWindow : nsISupports * Note that tooltips and noautohide popups won't be closed. */ void rollupAllPopups(); + + /** + * Normally, the window is shown when the first navigation completes. + * This method does everything that would be done after the first + * navigation right now for the initial viewer. + */ + void showInitialViewer(); };