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:
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;
}