commit 3e1a58787c7effe54ed6eda19a5b5acb2fb6fc94
parent e59372e02fa87e427d60e8eab9dfce2d37db078d
Author: Jeremy Swinarton <jswinarton@mozilla.com>
Date: Fri, 17 Oct 2025 18:53:21 +0000
Bug 1984732: Suppress animation when switching between tabs in a collapsed tab group r=dwalker,sthompson,desktop-theme-reviewers,tabbrowser-reviewers,dao
Differential Revision: https://phabricator.services.mozilla.com/D267290
Diffstat:
4 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/browser/components/tabbrowser/content/drag-and-drop.js b/browser/components/tabbrowser/content/drag-and-drop.js
@@ -1230,7 +1230,7 @@
// from appearing to move while the dragged tabs are positioned absolutely
let isTabInCollapsingGroup = expandGroupOnDrop && t.group == tab.group;
if (!movingTabsSet.has(t) && !isTabInCollapsingGroup) {
- t.style.transition = "none";
+ t.animationsEnabled = false;
suppressTransitionsFor.push(t);
}
}
@@ -1241,7 +1241,7 @@
.then(() => {
window.requestAnimationFrame(() => {
for (let t of suppressTransitionsFor) {
- t.style.transition = "";
+ t.animationsEnabled = true;
}
});
});
diff --git a/browser/components/tabbrowser/content/tab-hover-preview.mjs b/browser/components/tabbrowser/content/tab-hover-preview.mjs
@@ -604,6 +604,33 @@ class TabGroupPanel extends Panel {
handleEvent(event) {
if (event.type == "command") {
+ if (this.win.gBrowser.selectedTab == event.target.tab) {
+ this.deactivate({ force: true });
+ return;
+ }
+
+ // bug1984732: temporarily disable CSS transitions while tabs are
+ // switching to prevent an unsightly "slide" animation when switching
+ // tabs within a collapsed group
+ let switchingTabs = [this.win.gBrowser.selectedTab, event.target.tab];
+ if (switchingTabs.every(tab => tab.group == this.#group)) {
+ for (let tab of switchingTabs) {
+ tab.animationsEnabled = false;
+ }
+
+ this.win.addEventListener(
+ "TabSwitchDone",
+ () => {
+ this.win.requestAnimationFrame(() => {
+ for (let tab of switchingTabs) {
+ tab.animationsEnabled = true;
+ }
+ });
+ },
+ { once: true }
+ );
+ }
+
this.win.gBrowser.selectedTab = event.target.tab;
this.deactivate({ force: true });
} else if (event.type == "mouseout" && event.target == this.panelElement) {
diff --git a/browser/components/tabbrowser/content/tab.js b/browser/components/tabbrowser/content/tab.js
@@ -273,6 +273,14 @@
gBrowser._tabAttrModified(this, ["undiscardable"]);
}
+ get animationsEnabled() {
+ return this.style.transition == "";
+ }
+
+ set animationsEnabled(val) {
+ this.style.transition = val ? "" : "none";
+ }
+
get isEmpty() {
// Determines if a tab is "empty", usually used in the context of determining
// if it's ok to close the tab.
diff --git a/browser/components/tabbrowser/content/tabs.js b/browser/components/tabbrowser/content/tabs.js
@@ -1347,7 +1347,7 @@
tab.style.setProperty("max-width", aTabWidth, "important");
if (!isEndTab) {
// keep tabs the same width
- tab.style.transition = "none";
+ tab.animationsEnabled = false;
tabsToReset.push(tab);
}
}
@@ -1358,7 +1358,7 @@
.then(() => {
window.requestAnimationFrame(() => {
for (let tab of tabsToReset) {
- tab.style.transition = "";
+ tab.animationsEnabled = true;
}
});
});