tor-browser

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

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:
Mbrowser/components/tabbrowser/content/drag-and-drop.js | 4++--
Mbrowser/components/tabbrowser/content/tab-hover-preview.mjs | 27+++++++++++++++++++++++++++
Mbrowser/components/tabbrowser/content/tab.js | 8++++++++
Mbrowser/components/tabbrowser/content/tabs.js | 4++--
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; } }); });