commit 3a04ff1cc8bb61dd33224cd30b6512bda28c5d83
parent 6c4047cbb453260868cf6879dbd50cbf0bb871eb
Author: Jeremy Swinarton <jswinarton@mozilla.com>
Date: Mon, 10 Nov 2025 15:15:28 +0000
Bug 1980036: Suppress TGHP/THP panel activation logic if already open, and improve zero delay reset logic r=sthompson,tabbrowser-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D271393
Diffstat:
2 files changed, 33 insertions(+), 25 deletions(-)
diff --git a/browser/components/tabbrowser/content/tab-hover-preview.mjs b/browser/components/tabbrowser/content/tab-hover-preview.mjs
@@ -228,6 +228,7 @@ class TabPanel extends Panel {
}
activate(tab) {
+ let originalTab = this.#tab;
this.#tab = tab;
// Calling `moveToAnchor` in advance of the call to `openPopup` ensures
@@ -239,6 +240,9 @@ class TabPanel extends Panel {
// If the popup is closed this call will be ignored.
this.#movePanel();
+ originalTab?.removeEventListener("TabAttrModified", this);
+ this.#tab.addEventListener("TabAttrModified", this);
+
this.#thumbnailElement = null;
this.#maybeRequestThumbnail();
if (
@@ -246,16 +250,16 @@ class TabPanel extends Panel {
this.panelElement.state == "showing"
) {
this.#updatePreview();
+ } else {
+ this.#panelSet.panelOpener.execute(() => {
+ if (!this.#panelSet.shouldActivate()) {
+ return;
+ }
+ this.panelElement.openPopup(this.#tab, this.popupOptions);
+ }, this);
+ this.win.addEventListener("TabSelect", this);
+ this.panelElement.addEventListener("popupshowing", this);
}
- this.#panelSet.panelOpener.execute(() => {
- if (!this.#panelSet.shouldActivate()) {
- return;
- }
- this.panelElement.openPopup(this.#tab, this.popupOptions);
- }, this);
- this.win.addEventListener("TabSelect", this);
- this.panelElement.addEventListener("popupshowing", this);
- this.#tab.addEventListener("TabAttrModified", this);
}
deactivate(leavingTab = null) {
@@ -501,13 +505,16 @@ class TabGroupPanel extends Panel {
this.#group = group;
this.#movePanel();
this.#updatePanelContent();
+ Glean.tabgroup.groupInteractions.hover_preview.add();
- this.#panelSet.panelOpener.execute(() => {
- if (!this.#panelSet.shouldActivate() || !this.#group.collapsed) {
- return;
- }
- this.#doOpenPanel();
- }, this);
+ if (this.panelElement.state == "closed") {
+ this.#panelSet.panelOpener.execute(() => {
+ if (!this.#panelSet.shouldActivate() || !this.#group.collapsed) {
+ return;
+ }
+ this.#doOpenPanel();
+ }, this);
+ }
}
/**
@@ -576,8 +583,6 @@ class TabGroupPanel extends Panel {
}
this.panelElement.openPopup(this.#popupTarget, this.popupOptions);
-
- Glean.tabgroup.groupInteractions.hover_preview.add();
}
#updatePanelContent() {
@@ -698,7 +703,7 @@ class TabPreviewPanelTimedFunction {
/** @type {number | null} */
#timer;
- /** @type {boolean} */
+ /** @type {number | null} */
#useZeroDelay;
/** @type {function(): void | null} */
@@ -795,13 +800,12 @@ class TabPreviewPanelTimedFunction {
*/
setZeroDelay() {
if (this.#useZeroDelay) {
- return;
+ this.#win.clearTimeout(this.#useZeroDelay);
}
- this.#win.setTimeout(() => {
- this.#useZeroDelay = false;
+ this.#useZeroDelay = this.#win.setTimeout(() => {
+ this.#useZeroDelay = null;
}, this.#zeroDelayTime);
- this.#useZeroDelay = true;
}
get delayActive() {
diff --git a/browser/components/tabbrowser/test/browser/tabs/browser_tab_preview.js b/browser/components/tabbrowser/test/browser/tabs/browser_tab_preview.js
@@ -1059,7 +1059,10 @@ add_task(async function delayTests() {
*/
add_task(async function zeroDelayTests() {
await SpecialPowers.pushPrefEnv({
- set: [["ui.tooltip.delay_ms", 1000]],
+ set: [
+ ["ui.tooltip.delay_ms", 1000],
+ ["ui.prefersReducedMotion", 1],
+ ],
});
const tabUrl =
@@ -1074,12 +1077,13 @@ add_task(async function zeroDelayTests() {
resolved = true;
});
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
- let timeoutPromise = new Promise(resolve => setTimeout(resolve, 300));
+ let timeoutPromise = new Promise(resolve => setTimeout(resolve, 900));
await Promise.race([openPreviewPromise, timeoutPromise]);
- Assert.ok(resolved, "Zero delay is set immediately after leaving tab strip");
+ Assert.ok(resolved, "Panel was opened the second time without a delay");
await closeTabPreviews();
+
BrowserTestUtils.removeTab(tab);
await SpecialPowers.popPrefEnv();
await resetState();