diff --git a/src/browser/base/content/ZenUIManager.mjs b/src/browser/base/content/ZenUIManager.mjs
index cfde08211..46dff2042 100644
--- a/src/browser/base/content/ZenUIManager.mjs
+++ b/src/browser/base/content/ZenUIManager.mjs
@@ -149,11 +149,7 @@ var gZenUIManager = {
},
get newtabButton() {
- if (this._newtabButton) {
- return this._newtabButton;
- }
- this._newtabButton = document.getElementById('tabs-newtab-button');
- return this._newtabButton;
+ return ZenWorkspaces.activeWorkspaceStrip.querySelector('#tabs-newtab-button');
},
_prevUrlbarLabel: null,
diff --git a/src/browser/base/zen-components/ZenWorkspaces.mjs b/src/browser/base/zen-components/ZenWorkspaces.mjs
index c37cd4921..4a603d441 100644
--- a/src/browser/base/zen-components/ZenWorkspaces.mjs
+++ b/src/browser/base/zen-components/ZenWorkspaces.mjs
@@ -97,6 +97,47 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
);
}
+ get activeWorkspaceStrip() {
+ const activeWorkspace = this.activeWorkspace;
+ return document.querySelector(`.zen-workspace-tabs-section[zen-workspace-id="${activeWorkspace}"]`);
+ }
+
+ get tabboxChildren() {
+ if (!this.workspaceEnabled || !this._hasInitializedTabsStrip) {
+ return gBrowser.tabContainer.arrowScrollbox.children;
+ }
+ return this.activeWorkspaceStrip.children
+ }
+
+ async initializeTabsStripSections() {
+ const tabs = this.tabboxChildren;
+ const perifery = document.getElementById('tabbrowser-arrowscrollbox-periphery');
+ for (const workspace of (await this._workspaces()).workspaces) {
+ this._createWorkspaceTabsSection(workspace, tabs, perifery);
+ }
+ perifery.remove();
+ this._hasInitializedTabsStrip = true;
+ }
+
+ async _createWorkspaceTabsSection(workspace, tabs, perifery) {
+ const container = gBrowser.tabContainer.arrowScrollbox;
+ const section = document.createXULElement('vbox');
+ section.className = 'zen-workspace-tabs-section';
+ section.setAttribute('flex', '1');
+ section.setAttribute('zen-workspace-id', workspace.uuid);
+ container.appendChild(section);
+ this._organizeTabsToWorkspaceSections(workspace, section, tabs);
+ section.appendChild(perifery.cloneNode(true));
+ }
+
+ _organizeTabsToWorkspaceSections(workspace, section, tabs) {
+ const workspaceTabs = Array.from(tabs).filter((tab) => tab.getAttribute('zen-workspace-id') === workspace.uuid);
+ for (const tab of workspaceTabs) {
+ section.appendChild(tab);
+ }
+ this.tabContainer._invalidateCachedTabs();
+ }
+
initializeWorkspaceNavigation() {
this._setupAppCommandHandlers();
this._setupSidebarHandlers();
@@ -411,6 +452,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
this.activeWorkspace = activeWorkspace?.uuid;
}
}
+ await this.initializeTabsStripSections();
try {
if (activeWorkspace) {
window.gZenThemePicker = new ZenThemePicker();
@@ -1319,19 +1361,8 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
// Refresh tab cache
this.tabContainer._invalidateCachedTabs();
- let animationDirection;
if (previousWorkspace && !onInit && !this._animatingChange) {
- animationDirection =
- explicitAnimationDirection ??
- (workspaces.workspaces.findIndex((w) => w.uuid === previousWorkspace.uuid) <
- workspaces.workspaces.findIndex((w) => w.uuid === window.uuid)
- ? 'right'
- : 'left');
- }
- if (animationDirection) {
- // Animate tabs out of view before changing workspace, therefor we
- // need to animate in the opposite direction
- await this._animateTabs(animationDirection === 'left' ? 'right' : 'left', true);
+ await this._animateTabs(previousWorkspace, window);
}
// First pass: Handle tab visibility and workspace ID assignment
@@ -1343,9 +1374,6 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
// Update UI and state
await this._updateWorkspaceState(window, onInit);
- if (animationDirection) {
- await this._animateTabs(animationDirection);
- }
}
get _animateTabsElements() {
@@ -1354,35 +1382,31 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
return [...this.tabContainer.querySelectorAll(selector), ...this.tabContainer.querySelectorAll(extraSelector)];
}
- async _animateTabs(direction, out = false) {
- this.tabContainer.removeAttribute('dont-animate-tabs');
- const tabsWidth = this.tabContainer.getBoundingClientRect().width;
- // order by actual position in the children list to animate
- const elements = this._animateTabsElements;
- if (out) {
- const existingTransform = elements[0].style.transform;
- const newTransform = `translateX(${direction === 'left' ? '-' : ''}${tabsWidth}px)`;
- return gZenUIManager.motion.animate(
- elements,
- {
- transform: existingTransform ? [existingTransform, newTransform] : newTransform,
- },
- {
- type: 'spring',
- bounce: 0,
- duration: 0.12,
- }
- );
- }
- return gZenUIManager.motion.animate(
- elements,
+ async _animateTabs(previousWorkspace, newWorkspace) {
+ const newWorkspaceContainer = this.tabContainer;
+ const previousWorkspaceContainer = document.querySelector(`[zen-workspace-id="${previousWorkspace.uuid}"]`);
+
+ const newWorkspaceLeft = newWorkspaceContainer.getBoundingClientRect().left;
+ gZenUIManager.motion.animate(
+ newWorkspaceContainer,
{
- transform: [`translateX(${direction === 'left' ? '-' : ''}${tabsWidth}px)`, 'translateX(0px)'],
+ transform: [`translateX(${newWorkspaceLeft}px)`, 'translateX(0)'],
},
{
- duration: 0.15,
type: 'spring',
bounce: 0,
+ duration: 0.12,
+ }
+ );
+ gZenUIManager.motion.animate(
+ previousWorkspaceContainer,
+ {
+ transform: ['translateX(0)', `translateX(-${newWorkspaceLeft}px)`],
+ },
+ {
+ type: 'spring',
+ bounce: 0,
+ duration: 0.12,
}
);
}
diff --git a/src/browser/components/tabbrowser/content/tabs-js.patch b/src/browser/components/tabbrowser/content/tabs-js.patch
index 756161868..b0a668a3c 100644
--- a/src/browser/components/tabbrowser/content/tabs-js.patch
+++ b/src/browser/components/tabbrowser/content/tabs-js.patch
@@ -1,5 +1,5 @@
diff --git a/browser/components/tabbrowser/content/tabs.js b/browser/components/tabbrowser/content/tabs.js
-index 8aeb244ffca9f48661805f5b7d860b5896055562..bffa5e0be62e73f380adf558c5df3441bde7b604 100644
+index 8aeb244ffca9f48661805f5b7d860b5896055562..ef532d6b5d311cab5bc573c2d0aae6ceab5c1dcf 100644
--- a/browser/components/tabbrowser/content/tabs.js
+++ b/browser/components/tabbrowser/content/tabs.js
@@ -94,7 +94,7 @@
@@ -101,7 +101,16 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..bffa5e0be62e73f380adf558c5df3441
) {
delete draggedTab._dragData;
return;
-@@ -1512,9 +1525,19 @@
+@@ -1498,7 +1511,7 @@
+ if (this.#allTabs) {
+ return this.#allTabs;
+ }
+- let children = Array.from(this.arrowScrollbox.children);
++ let children = Array.from(ZenWorkspaces.tabboxChildren);
+ // remove arrowScrollbox periphery element
+ children.pop();
+
+@@ -1512,14 +1525,24 @@
}
this.#allTabs = [
@@ -122,6 +131,21 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..bffa5e0be62e73f380adf558c5df3441
return this.#allTabs;
}
+ get allGroups() {
+- let children = Array.from(this.arrowScrollbox.children);
++ let children = Array.from(ZenWorkspaces.tabboxChildren);
+ return children.filter(node => node.tagName == "tab-group");
+ }
+
+@@ -1577,7 +1600,7 @@
+ let verticalPinnedTabsContainer = document.getElementById(
+ "vertical-pinned-tabs-container"
+ );
+- let children = Array.from(this.arrowScrollbox.children);
++ let children = Array.from(ZenWorkspaces.tabboxChildren);
+
+ let focusableItems = [];
+ for (let child of children) {
@@ -1593,6 +1616,7 @@
}
diff --git a/src/toolkit/content/widgets/arrowscrollbox-js.patch b/src/toolkit/content/widgets/arrowscrollbox-js.patch
index ebfbd2dec..28739a036 100644
--- a/src/toolkit/content/widgets/arrowscrollbox-js.patch
+++ b/src/toolkit/content/widgets/arrowscrollbox-js.patch
@@ -1,7 +1,25 @@
diff --git a/toolkit/content/widgets/arrowscrollbox.js b/toolkit/content/widgets/arrowscrollbox.js
-index 328c770d275ebbaada8a44438eaf738b1a62d985..95460108c6356408170b8a4a40d55a8f0621756b 100644
+index 328c770d275ebbaada8a44438eaf738b1a62d985..070439e26bfe6a2299aa4b82ee4c434e143e1a20 100644
--- a/toolkit/content/widgets/arrowscrollbox.js
+++ b/toolkit/content/widgets/arrowscrollbox.js
+@@ -15,7 +15,7 @@
+ static get inheritedAttributes() {
+ return {
+ "#scrollbutton-up": "disabled=scrolledtostart",
+- scrollbox: "orient,align,pack,dir,smoothscroll",
++ scrollbox: "align,pack,dir,smoothscroll",
+ "#scrollbutton-down": "disabled=scrolledtoend",
+ };
+ }
+@@ -26,7 +26,7 @@
+
+
+
+-
++
+
+
+
@@ -98,6 +98,7 @@
let slot = this.shadowRoot.querySelector("slot");