tor-browser

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

commit 1a0061c0f6b06894dbf7899a15fe0b858793b8f1
parent c198264d6626ccba80187461ee755149186c55fb
Author: Greg Stoll <gstoll@mozilla.com>
Date:   Wed,  8 Oct 2025 23:48:25 +0000

Bug 1968297 - ensure windows that are occluded after session restore draw a taskbar preview (again x2) r=win-reviewers,sessionstore-reviewers,handyman,sfoster

The previous patches have made this better, but there's still a problem
if a window gets resized during session restore. (it's easiest to see this
if its natural size is small and then it gets maximized)

There are a number of ways to fix this, but I think delaying the "session
was restored" message until the window is resized makes sense, and that means
we can just extend the check for "should I pretend I'm not occluded" to
include if session restoring is in progress.

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

Diffstat:
Mbrowser/components/sessionstore/SessionStore.sys.mjs | 29++++++++++++++++++++---------
Mbrowser/components/sessionstore/test/browser_637020.js | 5++++-
Mwidget/windows/nsWindowGfx.cpp | 5+++--
3 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/browser/components/sessionstore/SessionStore.sys.mjs b/browser/components/sessionstore/SessionStore.sys.mjs @@ -5916,14 +5916,6 @@ var SessionStoreInternal = { arrowScrollbox.smoothScroll = smoothScroll; Glean.sessionRestore.restoreWindow.stopAndAccumulate(timerId); - - this._setWindowStateReady(aWindow); - - this._sendWindowRestoredNotification(aWindow); - - Services.obs.notifyObservers(aWindow, NOTIFY_SINGLE_WINDOW_RESTORED); - - this._sendRestoreCompletedNotifications(); }, /** @@ -5986,9 +5978,11 @@ var SessionStoreInternal = { _restoreWindowsFeaturesAndTabs(windows) { // First, we restore window features, so that when users start interacting // with a window, we don't steal the window focus. + let resizePromises = []; for (let window of windows) { let state = this._statesToRestore[WINDOW_RESTORE_IDS.get(window)]; - this.restoreWindowFeatures(window, state.windows[0]); + // Wait for these promises after we've restored data into them below. + resizePromises.push(this.restoreWindowFeatures(window, state.windows[0])); } // Then we restore data into windows. @@ -6001,6 +5995,20 @@ var SessionStoreInternal = { ); WINDOW_RESTORE_ZINDICES.delete(window); } + for (let resizePromise of resizePromises) { + resizePromise.then(resizedWindow => { + this._setWindowStateReady(resizedWindow); + + this._sendWindowRestoredNotification(resizedWindow); + + Services.obs.notifyObservers( + resizedWindow, + NOTIFY_SINGLE_WINDOW_RESTORED + ); + + this._sendRestoreCompletedNotifications(); + }); + } }, /** @@ -6505,6 +6513,7 @@ var SessionStoreInternal = { } } + let promiseParts = Promise.withResolvers(); aWindow.setTimeout(() => { this.restoreDimensions( aWindow, @@ -6516,7 +6525,9 @@ var SessionStoreInternal = { aWinData.sizemodeBeforeMinimized || "" ); this.restoreSidebar(aWindow, aWinData.sidebar, aWinData.isPopup); + promiseParts.resolve(aWindow); }, 0); + return promiseParts.promise; }, /** diff --git a/browser/components/sessionstore/test/browser_637020.js b/browser/components/sessionstore/test/browser_637020.js @@ -46,6 +46,9 @@ add_task(async function test() { let backupState = SessionStore.getBrowserState(); SessionStore.setBrowserState(JSON.stringify(TEST_STATE)); let win = await promiseWindow; + let delayedStartupFinished = new Promise(resolve => + whenDelayedStartupFinished(win, resolve) + ); let restoring = promiseWindowRestoring(win); let restored = promiseWindowRestored(win); await restoring; @@ -58,7 +61,7 @@ add_task(async function test() { // The history has now been restored and the tabs are loading. The data must // now come from the window, if it's correctly been marked as dirty before. - await new Promise(resolve => whenDelayedStartupFinished(win, resolve)); + await delayedStartupFinished; info("the delayed startup has finished"); checkWindows(); diff --git a/widget/windows/nsWindowGfx.cpp b/widget/windows/nsWindowGfx.cpp @@ -317,9 +317,10 @@ void nsWindow::NotifyOcclusionState(mozilla::widget::OcclusionState aState) { if (mFrameState->GetSizeMode() == nsSizeMode_Minimized) { isFullyOccluded = false; } - if (isFullyOccluded && !mHasBeenShown) { + if (isFullyOccluded && (!mHasBeenShown || nsWindow::sIsRestoringSession)) { // Don't mark a newly-created window as occluded until - // it renders a taskbar icon. (bug 1968297) + // it is finished being restored (including sizing) and has been shown once. + // (bug 1968297) isFullyOccluded = false; }