From 69217407a80933bdaa052c299725d66b20750ec3 Mon Sep 17 00:00:00 2001 From: "mr. m" <91018726+mr-cheffy@users.noreply.github.com> Date: Tue, 5 May 2026 11:37:46 +0200 Subject: [PATCH] gh-12699: Fixed switching windoww focus causing blinks (gh-13568) --- src/zen/sessionstore/ZenWindowSync.sys.mjs | 25 +++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/zen/sessionstore/ZenWindowSync.sys.mjs b/src/zen/sessionstore/ZenWindowSync.sys.mjs index bc90b80c2..a8b0f69a1 100644 --- a/src/zen/sessionstore/ZenWindowSync.sys.mjs +++ b/src/zen/sessionstore/ZenWindowSync.sys.mjs @@ -97,11 +97,11 @@ class nsZenWindowSync { }; /** - * Promise that resolves when the current docshell swap operation is finished. + * Promise|null that resolves when the current docshell swap operation is finished. * Used to avoid multiple simultaneous swap operations that could interfere with each other. * For example, when focusing a window AND selecting a tab at the same time. */ - #docShellSwitchPromise = Promise.resolve(); + #docShellSwitchPromise = null; /** * Map of sync handlers for different event types. @@ -1485,18 +1485,29 @@ class nsZenWindowSync { ) { return; } - let promise = this.#docShellSwitchPromise; + if (this.#docShellSwitchPromise) { + return; + } + const onTabSelect = event => { + if (event.detail?.previousTab === event.target) { + return; + } + this.#lastSelectedTab = null; + this.on_TabSelect(event, { ignorePromise: true }); + }; this.#lastFocusedWindow = new WeakRef(window); this.#lastSelectedTab = new WeakRef(window.gBrowser.selectedTab); + window.addEventListener("TabSelect", onTabSelect, { once: true }); // eslint-disable-next-line no-async-promise-executor this.#docShellSwitchPromise = new Promise(async resolve => { - await promise; await this.#onTabSwitchOrWindowFocus(window); + window.removeEventListener("TabSelect", onTabSelect); resolve(); + this.#docShellSwitchPromise = null; }); } - on_TabSelect(aEvent) { + on_TabSelect(aEvent, { ignorePromise = false } = {}) { const tab = aEvent.target; if (this.#lastSelectedTab?.deref() === tab) { return; @@ -1504,11 +1515,15 @@ class nsZenWindowSync { this.#lastSelectedTab = new WeakRef(tab); const previousTab = aEvent.detail.previousTab; let promise = this.#docShellSwitchPromise; + if (promise && !ignorePromise) { + return; + } // eslint-disable-next-line no-async-promise-executor this.#docShellSwitchPromise = new Promise(async resolve => { await promise; await this.#onTabSwitchOrWindowFocus(tab.ownerGlobal, previousTab); resolve(); + this.#docShellSwitchPromise = null; }); }