From 22cad83c8fc08c565734e9cd0af8d1c9fce0ea06 Mon Sep 17 00:00:00 2001 From: "mr. m" Date: Wed, 12 Feb 2025 10:58:53 +0100 Subject: [PATCH 01/33] Fixed creating a new workspace in the new system --- src/browser/base/content/zen-styles/zen-workspaces.css | 2 +- src/browser/base/zen-components/ZenWorkspaces.mjs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/browser/base/content/zen-styles/zen-workspaces.css b/src/browser/base/content/zen-styles/zen-workspaces.css index 9fbe38108..32f2a7c9a 100644 --- a/src/browser/base/content/zen-styles/zen-workspaces.css +++ b/src/browser/base/content/zen-styles/zen-workspaces.css @@ -456,7 +456,7 @@ position: absolute; max-height: var(--zen-workspace-indicator-height); min-height: var(--zen-workspace-indicator-height); - gap: 5px; + gap: 12px; overflow: hidden; text-overflow: ellipsis; flex-direction: row !important; diff --git a/src/browser/base/zen-components/ZenWorkspaces.mjs b/src/browser/base/zen-components/ZenWorkspaces.mjs index 117a3dd15..636ab27d8 100644 --- a/src/browser/base/zen-components/ZenWorkspaces.mjs +++ b/src/browser/base/zen-components/ZenWorkspaces.mjs @@ -1703,9 +1703,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { }; this._prepareNewWorkspace(window); const perifery = document.querySelector('#tabbrowser-arrowscrollbox-periphery[hidden]'); - preifery?.removeAttribute('hidden'); + perifery?.removeAttribute('hidden'); this._createWorkspaceTabsSection(window, [], perifery); - preifery.setAttribute('hidden', 'true'); + perifery.setAttribute('hidden', 'true'); return window; } From 40a843200f3abba7aeb94d95c08db014542cb855 Mon Sep 17 00:00:00 2001 From: "mr. m" Date: Wed, 12 Feb 2025 12:39:13 +0100 Subject: [PATCH 02/33] Fixed unpinning tabs --- .../content/zen-styles/zen-tabs/vertical-tabs.css | 2 +- src/browser/base/zen-components/ZenWorkspaces.mjs | 11 ++++++----- .../components/tabbrowser/content/tabbrowser-js.patch | 10 +++++++--- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css b/src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css index b18d303c6..56415a234 100644 --- a/src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css +++ b/src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css @@ -369,7 +369,7 @@ #zen-browser-tabs-wrapper { min-height: fit-content; overflow-y: auto; - overflow-x: hidden; + overflow-x: clip; height: 100%; scrollbar-width: thin; } diff --git a/src/browser/base/zen-components/ZenWorkspaces.mjs b/src/browser/base/zen-components/ZenWorkspaces.mjs index 636ab27d8..50a830328 100644 --- a/src/browser/base/zen-components/ZenWorkspaces.mjs +++ b/src/browser/base/zen-components/ZenWorkspaces.mjs @@ -359,7 +359,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { event.preventDefault(); event.stopPropagation(); - const delta = event.delta * 500; + const delta = event.delta * 300; this._swipeState.lastDelta = delta; if (Math.abs(delta) > 1) { @@ -1625,9 +1625,11 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { this._lastSelectedWorkspaceTabs[window.uuid] = newTab; } // Always make sure we always unselect the tab from the old workspace - currentSelectedTab._selected = false; - currentSelectedTab._visuallySelected = true; // we do want to animate the tab deselection - this._beforeSelectedTab = currentSelectedTab; + if (currentSelectedTab && currentSelectedTab !== tabToSelect) { + currentSelectedTab._selected = false; + currentSelectedTab._visuallySelected = true; // we do want to animate the tab deselection + this._beforeSelectedTab = currentSelectedTab; + } } async _updateWorkspaceState(window, onInit) { @@ -1639,7 +1641,6 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { // Update workspace UI await this._updateWorkspacesChangeContextMenu(); - document.getElementById('tabbrowser-tabs')._positionPinnedTabs(); gZenUIManager.updateTabsToolbar(); await this._propagateWorkspaceData({ clearCache: false }); diff --git a/src/browser/components/tabbrowser/content/tabbrowser-js.patch b/src/browser/components/tabbrowser/content/tabbrowser-js.patch index e5ba04639..1e2d0b8fc 100644 --- a/src/browser/components/tabbrowser/content/tabbrowser-js.patch +++ b/src/browser/components/tabbrowser/content/tabbrowser-js.patch @@ -1,5 +1,5 @@ diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js -index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..c90119b4b248887fd8612beb9aac83c6eeb57088 100644 +index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..cbeb4472fdc7dc12c2a45a0c578d166c1cac1b6b 100644 --- a/browser/components/tabbrowser/content/tabbrowser.js +++ b/browser/components/tabbrowser/content/tabbrowser.js @@ -406,11 +406,39 @@ @@ -57,8 +57,12 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..c90119b4b248887fd8612beb9aac83c6 } aTab.setAttribute("pinned", "true"); this._updateTabBarForPinnedTabs(); -@@ -831,7 +859,7 @@ - this.tabContainer.arrowScrollbox.prepend(aTab); +@@ -828,10 +856,10 @@ + // the moving of a tab from the vertical pinned tabs container + // and back into arrowscrollbox. + aTab.removeAttribute("pinned"); +- this.tabContainer.arrowScrollbox.prepend(aTab); ++ ZenWorkspaces.activeWorkspaceStrip.prepend(aTab); }); } else { - this.moveTabTo(aTab, this.pinnedTabCount - 1, { From bd4f9788ccb851cd4300ea5c188f0981f1e06cbb Mon Sep 17 00:00:00 2001 From: "mr. m" Date: Wed, 12 Feb 2025 13:16:20 +0100 Subject: [PATCH 03/33] Fixed urlbar glitching when focusing in compact mode --- src/browser/components/urlbar/UrlbarInput-sys-mjs.patch | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/browser/components/urlbar/UrlbarInput-sys-mjs.patch b/src/browser/components/urlbar/UrlbarInput-sys-mjs.patch index f395eaa62..3871b2fe8 100644 --- a/src/browser/components/urlbar/UrlbarInput-sys-mjs.patch +++ b/src/browser/components/urlbar/UrlbarInput-sys-mjs.patch @@ -1,5 +1,5 @@ diff --git a/browser/components/urlbar/UrlbarInput.sys.mjs b/browser/components/urlbar/UrlbarInput.sys.mjs -index 50968dc04b527438acf30151f0c2e92f8b45097c..ea9207399b205c84d1263a4de8a63b776e36eabd 100644 +index 50968dc04b527438acf30151f0c2e92f8b45097c..f8587b68ac057bb0f829fc21f08ade6605b14c92 100644 --- a/browser/components/urlbar/UrlbarInput.sys.mjs +++ b/browser/components/urlbar/UrlbarInput.sys.mjs @@ -67,6 +67,13 @@ XPCOMUtils.defineLazyPreferenceGetter( @@ -20,7 +20,7 @@ index 50968dc04b527438acf30151f0c2e92f8b45097c..ea9207399b205c84d1263a4de8a63b77 // See _on_select(). HTMLInputElement.select() dispatches a "select" // event but does not set the primary selection. this._suppressPrimaryAdjustment = true; -+ this.document.getElementById("navigator-toolbox").setAttribute("supress-primary-adjustment", true); ++ this.document.getElementById("navigator-toolbox").setAttribute("supress-primary-adjustment", !this.document.getElementById("navigator-toolbox").hasAttribute("zen-has-hover")); this.inputField.select(); + this.document.ownerGlobal.setTimeout(() => { + this.document.getElementById("navigator-toolbox").removeAttribute("supress-primary-adjustment"); @@ -44,7 +44,7 @@ index 50968dc04b527438acf30151f0c2e92f8b45097c..ea9207399b205c84d1263a4de8a63b77 } } - -+ this.document.getElementById("navigator-toolbox").setAttribute("supress-primary-adjustment", true); ++ this.document.getElementById("navigator-toolbox").setAttribute("supress-primary-adjustment", !this.document.getElementById("navigator-toolbox").hasAttribute("zen-has-hover")); this.handleNavigation({ event }); + this.document.ownerGlobal.setTimeout(() => { + this.document.getElementById("navigator-toolbox").removeAttribute("supress-primary-adjustment"); From 23d9487ca7957b5608682ccd54722eee1baa14ac Mon Sep 17 00:00:00 2001 From: "mr. m" Date: Wed, 12 Feb 2025 15:35:37 +0100 Subject: [PATCH 04/33] Fixed pinned tabs separator using the wrong tabs when hiding --- .../zen-styles/zen-tabs/vertical-tabs.css | 3 +-- .../base/zen-components/ZenWorkspaces.mjs | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css b/src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css index 56415a234..2c530b8df 100644 --- a/src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css +++ b/src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css @@ -126,8 +126,7 @@ width: 98%; transition: margin 0.2s ease-in-out, background 0.2s ease-in-out, max-height 0.2s ease-in-out; - #vertical-pinned-tabs-container .zen-workspace-tabs-section[active]:not(:has(tab:not([hidden]))) &, - #tabbrowser-tabs:not(:has(#tabbrowser-arrowscrollbox .zen-workspace-tabs-section[active] tab:not([hidden]))) & { + #vertical-pinned-tabs-container .zen-workspace-tabs-section[hide-separator] & { max-height: 0; margin: 0 auto; } diff --git a/src/browser/base/zen-components/ZenWorkspaces.mjs b/src/browser/base/zen-components/ZenWorkspaces.mjs index 50a830328..4535abca0 100644 --- a/src/browser/base/zen-components/ZenWorkspaces.mjs +++ b/src/browser/base/zen-components/ZenWorkspaces.mjs @@ -509,6 +509,8 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { this._initializeWorkspaceTabContextMenus(); await this.workspaceBookmarks(); window.addEventListener('TabBrowserInserted', this.onTabBrowserInserted.bind(this)); + window.addEventListener('TabOpen', this.updateTabsContainers.bind(this)); + window.addEventListener('TabClose', this.updateTabsContainers.bind(this)); let workspaces = await this._workspaces(); let activeWorkspace = null; if (workspaces.workspaces.length === 0) { @@ -1721,6 +1723,19 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { return workspaceData; } + updateTabsContainers() { + this.onPinnedTabsResize([this.pinnedTabsContainer]); + } + + updateShouldHideSeparator(arrowScrollbox, pinnedContainer) { + const shouldHideSeparator = pinnedContainer.children.length === 1 || arrowScrollbox.children.length === 1; + if (shouldHideSeparator) { + pinnedContainer.setAttribute('hide-separator', 'true'); + } else { + pinnedContainer.removeAttribute('hide-separator'); + } + } + onPinnedTabsResize(entries) { if (!this.workspaceEnabled) { return; @@ -1731,6 +1746,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { `#tabbrowser-arrowscrollbox .zen-workspace-tabs-section[zen-workspace-id="${workspaceId}"]` ); this._updateMarginTopPinnedTabs(arrowScrollbox, entry.target); + this.updateShouldHideSeparator(arrowScrollbox, entry.target); } } From aebc2c9660957926eba04cb654ca1eac835ac8c8 Mon Sep 17 00:00:00 2001 From: "mr. m" Date: Wed, 12 Feb 2025 15:36:59 +0100 Subject: [PATCH 05/33] Fixed handling tab opens/close on workspaces --- src/browser/base/zen-components/ZenWorkspaces.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/base/zen-components/ZenWorkspaces.mjs b/src/browser/base/zen-components/ZenWorkspaces.mjs index 4535abca0..803854dd5 100644 --- a/src/browser/base/zen-components/ZenWorkspaces.mjs +++ b/src/browser/base/zen-components/ZenWorkspaces.mjs @@ -1724,7 +1724,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } updateTabsContainers() { - this.onPinnedTabsResize([this.pinnedTabsContainer]); + this.onPinnedTabsResize([{ target: this.pinnedTabsContainer }]); } updateShouldHideSeparator(arrowScrollbox, pinnedContainer) { From 9f6fbc5e57616d8a0daf9bafc304a0b8f9957047 Mon Sep 17 00:00:00 2001 From: "mr. M" Date: Wed, 12 Feb 2025 20:03:00 +0100 Subject: [PATCH 06/33] Refactor tab handling and session restore logic for improved workspace management --- .../zen-styles/zen-tabs/vertical-tabs.css | 4 +- .../base/zen-components/ZenWorkspaces.mjs | 41 ++++++++++++++++++- .../sessionstore/SessionStore-sys-mjs.patch | 13 +++++- .../tabbrowser/content/tabbrowser-js.patch | 10 ++--- .../tabbrowser/content/tabs-js.patch | 37 +++++++++-------- surfer.json | 2 +- 6 files changed, 79 insertions(+), 28 deletions(-) diff --git a/src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css b/src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css index 2c530b8df..68c7d8624 100644 --- a/src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css +++ b/src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css @@ -371,6 +371,7 @@ overflow-x: clip; height: 100%; scrollbar-width: thin; + position: relative; } #vertical-pinned-tabs-container { @@ -378,7 +379,8 @@ display: flex !important; flex-direction: column; min-height: fit-content !important; - overflow: visible; + overflow-x: clip; + overflow-y: visible; max-height: unset !important; & .tabbrowser-tab:not(:hover) .tab-background:not([selected]):not([multiselected]) { diff --git a/src/browser/base/zen-components/ZenWorkspaces.mjs b/src/browser/base/zen-components/ZenWorkspaces.mjs index 803854dd5..9ecf698ed 100644 --- a/src/browser/base/zen-components/ZenWorkspaces.mjs +++ b/src/browser/base/zen-components/ZenWorkspaces.mjs @@ -1308,7 +1308,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } tab.setAttribute('zen-workspace-id', workspaceID); const parent = tab.pinned ? '#zen-browser-tabs-pinned ' : '#zen-browser-tabs '; - const container = document.querySelector(parent + '.zen-browser-tabs-container'); + const container = document.querySelector(parent + '.zen-workspace-tabs-section'); if (container) { container.insertBefore(tab, container.firstChild); } @@ -2043,4 +2043,43 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { // Return true only if the bookmark is in another workspace and not in the active one return isInOtherWorkspace && !isInActiveWorkspace; } + + // Session restore functions + get allStoredTabs() { + if (!this._hasInitializedTabsStrip) { + const children = Array.from(this.tabboxChildren); + children.pop(); // Remove the last child which is the new tab button + return children; + } + + const tabs = []; + // we need to go through each tab in each container + const essentialsContainer = document.getElementById('zen-essentials-container'); + const pinnedContainers = document.querySelectorAll('#vertical-pinned-tabs-container .zen-workspace-tabs-section'); + const normalContainers = document.querySelectorAll('#tabbrowser-arrowscrollbox .zen-workspace-tabs-section'); + const containers = [essentialsContainer, ...pinnedContainers, ...normalContainers]; + for (const container of containers) { + for (const tab of container.children) { + if (tab.tagName === 'tab' || tab.tagName == 'tab-group') { + tabs.push(tab); + } + } + } + return tabs; + } + + get pinnedTabCount() { + return this.pinnedTabsContainer.children.length - 1; + } + + get normalTabCount() { + return this.tabboxChildren.length - 1; + } + + get allWorkspaceTabs() { + const currentWorkspace = this.activeWorkspace; + return this.allStoredTabs.filter( + (tab) => tab.hasAttribute('zen-essential') || tab.getAttribute('zen-workspace-id') === currentWorkspace + ); + } })(); diff --git a/src/browser/components/sessionstore/SessionStore-sys-mjs.patch b/src/browser/components/sessionstore/SessionStore-sys-mjs.patch index 85c7071f7..2c7b2688f 100644 --- a/src/browser/components/sessionstore/SessionStore-sys-mjs.patch +++ b/src/browser/components/sessionstore/SessionStore-sys-mjs.patch @@ -1,8 +1,8 @@ diff --git a/browser/components/sessionstore/SessionStore.sys.mjs b/browser/components/sessionstore/SessionStore.sys.mjs -index 8125c1afc07f3365a2ad030adaf6a560453d7fe6..2856c5f93bfc9d68b98e09b2f26e3d5266c1f46a 100644 +index 908743177d9f95e2e6549c689e7a493ca8668701..b452d7dfc93f6171f8a65668e052a37638f1f6c3 100644 --- a/browser/components/sessionstore/SessionStore.sys.mjs +++ b/browser/components/sessionstore/SessionStore.sys.mjs -@@ -3679,6 +3679,7 @@ var SessionStoreInternal = { +@@ -3848,6 +3848,7 @@ var SessionStoreInternal = { aWindow.gBrowser.selectedTab = newTab; } @@ -10,3 +10,12 @@ index 8125c1afc07f3365a2ad030adaf6a560453d7fe6..2856c5f93bfc9d68b98e09b2f26e3d52 // Restore the state into the new tab. this.restoreTab(newTab, tabState, { restoreImmediately: aRestoreImmediately, +@@ -5315,7 +5316,7 @@ var SessionStoreInternal = { + } + + let tabbrowser = aWindow.gBrowser; +- let tabs = tabbrowser.tabs; ++ let tabs = aWindow.ZenWorkspaces.allStoredTabs; + /** @type {WindowStateData} */ + let winData = this._windows[aWindow.__SSi]; + let tabsData = (winData.tabs = []); diff --git a/src/browser/components/tabbrowser/content/tabbrowser-js.patch b/src/browser/components/tabbrowser/content/tabbrowser-js.patch index 1e2d0b8fc..e5ba04639 100644 --- a/src/browser/components/tabbrowser/content/tabbrowser-js.patch +++ b/src/browser/components/tabbrowser/content/tabbrowser-js.patch @@ -1,5 +1,5 @@ diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js -index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..cbeb4472fdc7dc12c2a45a0c578d166c1cac1b6b 100644 +index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..c90119b4b248887fd8612beb9aac83c6eeb57088 100644 --- a/browser/components/tabbrowser/content/tabbrowser.js +++ b/browser/components/tabbrowser/content/tabbrowser.js @@ -406,11 +406,39 @@ @@ -57,12 +57,8 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..cbeb4472fdc7dc12c2a45a0c578d166c } aTab.setAttribute("pinned", "true"); this._updateTabBarForPinnedTabs(); -@@ -828,10 +856,10 @@ - // the moving of a tab from the vertical pinned tabs container - // and back into arrowscrollbox. - aTab.removeAttribute("pinned"); -- this.tabContainer.arrowScrollbox.prepend(aTab); -+ ZenWorkspaces.activeWorkspaceStrip.prepend(aTab); +@@ -831,7 +859,7 @@ + this.tabContainer.arrowScrollbox.prepend(aTab); }); } else { - this.moveTabTo(aTab, this.pinnedTabCount - 1, { diff --git a/src/browser/components/tabbrowser/content/tabs-js.patch b/src/browser/components/tabbrowser/content/tabs-js.patch index 149134733..dfafb0b6c 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..ab0a6a6ed80608385b4663775b4edf67709dae7d 100644 +index 8aeb244ffca9f48661805f5b7d860b5896055562..f7866af6f5b72e2704a87148300a391b20e112db 100644 --- a/browser/components/tabbrowser/content/tabs.js +++ b/browser/components/tabbrowser/content/tabs.js @@ -94,7 +94,7 @@ @@ -209,7 +209,12 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 if (tab && rect(tab).width <= this._tabClipWidth) { this.setAttribute("closebuttons", "activetab"); } else { -@@ -1832,6 +1858,7 @@ +@@ -1828,10 +1854,12 @@ + + _handleTabSelect(aInstant) { + let selectedTab = this.selectedItem; ++ if (!selectedTab) return; + if (this.overflowing) { this.arrowScrollbox.ensureElementIsVisible(selectedTab, aInstant); } @@ -217,7 +222,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 selectedTab._notselectedsinceload = false; } -@@ -1843,7 +1870,7 @@ +@@ -1843,7 +1871,7 @@ return; } @@ -226,7 +231,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 if (!tabs.length) { return; } -@@ -1879,7 +1906,7 @@ +@@ -1879,7 +1907,7 @@ if (isEndTab && !this._hasTabTempMaxWidth) { return; } @@ -235,7 +240,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 // Force tabs to stay the same width, unless we're closing the last tab, // which case we need to let them expand just enough so that the overall // tabbar width is the same. -@@ -1894,7 +1921,7 @@ +@@ -1894,7 +1922,7 @@ let tabsToReset = []; for (let i = numPinned; i < tabs.length; i++) { let tab = tabs[i]; @@ -244,7 +249,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 if (!isEndTab) { // keep tabs the same width tab.style.transition = "none"; -@@ -1960,16 +1987,15 @@ +@@ -1960,16 +1988,15 @@ // Move pinned tabs to another container when the tabstrip is toggled to vertical // and when session restore code calls _positionPinnedTabs; update styling whenever // the number of pinned tabs changes. @@ -266,7 +271,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 } } -@@ -1977,9 +2003,7 @@ +@@ -1977,9 +2004,7 @@ } _resetVerticalPinnedTabs() { @@ -277,7 +282,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 if (!verticalTabsContainer.children.length) { return; -@@ -1992,8 +2016,8 @@ +@@ -1992,8 +2017,8 @@ } _positionPinnedTabs() { @@ -288,7 +293,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 let absPositionHorizontalTabs = this.overflowing && tabs.length > numPinned && numPinned > 0; -@@ -2074,7 +2098,7 @@ +@@ -2074,7 +2099,7 @@ return; } @@ -297,7 +302,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 let directionX = screenX > dragData.animLastScreenX; let directionY = screenY > dragData.animLastScreenY; -@@ -2257,9 +2281,9 @@ +@@ -2257,9 +2282,9 @@ } let pinned = draggedTab.pinned; @@ -310,7 +315,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 pinned ? numPinned : undefined ); -@@ -2502,8 +2526,9 @@ +@@ -2502,8 +2527,9 @@ ); } @@ -322,7 +327,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 return; } -@@ -2668,9 +2693,9 @@ +@@ -2668,9 +2694,9 @@ function newIndex(aTab, index) { // Don't allow mixing pinned and unpinned tabs. if (aTab.pinned) { @@ -334,7 +339,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 } } -@@ -2754,7 +2779,7 @@ +@@ -2754,7 +2780,7 @@ } _notifyBackgroundTab(aTab) { @@ -343,7 +348,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 return; } -@@ -2772,12 +2797,14 @@ +@@ -2772,12 +2798,14 @@ selectedTab = { left: selectedTab.left, right: selectedTab.right, @@ -359,7 +364,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 selectedTab, ]; }) -@@ -2794,8 +2821,11 @@ +@@ -2794,8 +2822,11 @@ delete this._lastTabToScrollIntoView; // Is the new tab already completely visible? if ( @@ -373,7 +378,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 ) { return; } -@@ -2803,21 +2833,29 @@ +@@ -2803,21 +2834,29 @@ if (this.arrowScrollbox.smoothScroll) { // Can we make both the new tab and the selected tab completely visible? if ( diff --git a/surfer.json b/surfer.json index 96ac3b992..8b97e5388 100644 --- a/surfer.json +++ b/surfer.json @@ -53,4 +53,4 @@ "licenseType": "MPL-2.0" }, "updateHostname": "updates.zen-browser.app" -} +} \ No newline at end of file From d16992f5b21ea5e3bb2aff560a0eda5a541ef606 Mon Sep 17 00:00:00 2001 From: "mr. M" Date: Wed, 12 Feb 2025 20:05:56 +0100 Subject: [PATCH 07/33] Force overflow-x clipping in vertical tabs to ensure consistent styling --- src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css b/src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css index 68c7d8624..a5ca41b3f 100644 --- a/src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css +++ b/src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css @@ -368,7 +368,7 @@ #zen-browser-tabs-wrapper { min-height: fit-content; overflow-y: auto; - overflow-x: clip; + overflow-x: clip !important; /* might break custom css with new design, so let's force it */ height: 100%; scrollbar-width: thin; position: relative; From 8b98469936ff756cb4c53a22dfb3382555aa1a5d Mon Sep 17 00:00:00 2001 From: "mr. M" Date: Wed, 12 Feb 2025 21:38:05 +0100 Subject: [PATCH 08/33] Added support for acrylic backgrounds for windows 11 with mica support --- .../libpref/init/StaticPrefList-yaml.patch | 13 +++++++++--- src/widget/windows/nsWindow-cpp.patch | 21 +++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 src/widget/windows/nsWindow-cpp.patch diff --git a/src/modules/libpref/init/StaticPrefList-yaml.patch b/src/modules/libpref/init/StaticPrefList-yaml.patch index 6d3166133..fadcff2b1 100644 --- a/src/modules/libpref/init/StaticPrefList-yaml.patch +++ b/src/modules/libpref/init/StaticPrefList-yaml.patch @@ -1,8 +1,8 @@ diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml -index 5c5992d7b32e4c16d6a92815ca6fd54e8fcec824..6c8e67e36f02b578c800fa460868135afb73c66b 100644 +index 7364514f74703184462e8dbce3f0aafc3f850a3d..560671beddf6c216e918a47bd5dbd4e770a24ec7 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml -@@ -17810,7 +17810,7 @@ +@@ -18067,7 +18067,7 @@ # Whether we use the mica backdrop. Off by default for now. - name: widget.windows.mica type: bool @@ -11,7 +11,7 @@ index 5c5992d7b32e4c16d6a92815ca6fd54e8fcec824..6c8e67e36f02b578c800fa460868135a mirror: once #endif -@@ -17923,6 +17923,19 @@ +@@ -18180,6 +18180,26 @@ mirror: always #endif @@ -27,6 +27,13 @@ index 5c5992d7b32e4c16d6a92815ca6fd54e8fcec824..6c8e67e36f02b578c800fa460868135a + value: false + mirror: always +#endif ++ ++#ifdef XP_WIN ++- name: zen.widget.windows.acrylic ++ type: bool ++ value: true ++ mirror: once ++#endif + #--------------------------------------------------------------------------- # Prefs starting with "zoom." diff --git a/src/widget/windows/nsWindow-cpp.patch b/src/widget/windows/nsWindow-cpp.patch new file mode 100644 index 000000000..99fe82efa --- /dev/null +++ b/src/widget/windows/nsWindow-cpp.patch @@ -0,0 +1,21 @@ +diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp +index b735e78b1c2f3e0d85a5224311cdc746007c7eac..50f3c6e40b11220b71a8a3811305661887bb4360 100644 +--- a/widget/windows/nsWindow.cpp ++++ b/widget/windows/nsWindow.cpp +@@ -165,6 +165,7 @@ + #include "mozilla/StaticPrefs_layout.h" + #include "mozilla/StaticPrefs_ui.h" + #include "mozilla/StaticPrefs_widget.h" ++#include "mozilla/StaticPrefs_zen.h" + #include "nsNativeAppSupportWin.h" + + #include "nsIGfxInfo.h" +@@ -1071,7 +1072,7 @@ nsresult nsWindow::Create(nsIWidget* aParent, const LayoutDeviceIntRect& aRect, + + if (WinUtils::MicaEnabled() && !IsPopup()) { + // Enable Mica Alt Material if available. +- const DWM_SYSTEMBACKDROP_TYPE tabbedWindow = DWMSBT_TABBEDWINDOW; ++ const DWM_SYSTEMBACKDROP_TYPE tabbedWindow = StaticPrefs::zen_widget_windows_acrylic_AtStartup() ? DWMSBT_TRANSIENTWINDOW : DWMSBT_TABBEDWINDOW; + DwmSetWindowAttribute(mWnd, DWMWA_SYSTEMBACKDROP_TYPE, &tabbedWindow, + sizeof tabbedWindow); + } From 4f41aab3fabebce9b90eab7f8adf411da788b280 Mon Sep 17 00:00:00 2001 From: "mr. m" Date: Thu, 13 Feb 2025 11:00:56 +0100 Subject: [PATCH 09/33] merge --- .../base/zen-components/ZenWorkspaces.mjs | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/browser/base/zen-components/ZenWorkspaces.mjs b/src/browser/base/zen-components/ZenWorkspaces.mjs index 803854dd5..2fa911df9 100644 --- a/src/browser/base/zen-components/ZenWorkspaces.mjs +++ b/src/browser/base/zen-components/ZenWorkspaces.mjs @@ -1440,11 +1440,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { // Second pass: Handle tab selection this.tabContainer._invalidateCachedTabs(); - await this._handleTabSelection(window, onInit, containerId, workspaces, previousWorkspace.uuid); - this.tabContainer._updateVerticalPinnedTabs(); + const tabToSelect = await this._handleTabSelection(window, onInit, containerId, workspaces, previousWorkspace.uuid); // Update UI and state - await this._updateWorkspaceState(window, onInit); + await this._updateWorkspaceState(window, onInit, tabToSelect); } _updateMarginTopPinnedTabs(arrowscrollbox, pinnedContainer) { @@ -1540,10 +1539,6 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } } await Promise.all(animations); - if (this._beforeSelectedTab) { - this._beforeSelectedTab._visuallySelected = false; - this._beforeSelectedTab = null; - } this._animatingChange = false; } @@ -1617,21 +1612,19 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } // If we found a tab to select, select it - if (tabToSelect) { - gBrowser.selectedTab = tabToSelect; - this._lastSelectedWorkspaceTabs[window.uuid] = tabToSelect; - } else if (!onInit) { + if (!onInit && !tabToSelect) { // Create new tab if needed and no suitable tab was found const newTab = this._createNewTabForWorkspace(window); - gBrowser.selectedTab = newTab; - this._lastSelectedWorkspaceTabs[window.uuid] = newTab; + tabToSelect = newTab; } + tabToSelect._visuallySelected = true; + this._lastSelectedWorkspaceTabs[window.uuid] = tabToSelect; + // Always make sure we always unselect the tab from the old workspace if (currentSelectedTab && currentSelectedTab !== tabToSelect) { currentSelectedTab._selected = false; - currentSelectedTab._visuallySelected = true; // we do want to animate the tab deselection - this._beforeSelectedTab = currentSelectedTab; } + return tabToSelect; } async _updateWorkspaceState(window, onInit) { @@ -1659,7 +1652,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { this._invalidateBookmarkContainers(); // Update workspace indicator - await this.updateWorkspaceIndicator(); + await this.updateWorkspaceIndicator(window, this.workspaceIndicator); } _invalidateBookmarkContainers() { From ab836eb762606f1aba1df2ee0676c06f953f239d Mon Sep 17 00:00:00 2001 From: "mr. m" Date: Thu, 13 Feb 2025 11:16:16 +0100 Subject: [PATCH 10/33] Fixed workspace switching --- src/browser/base/zen-components/ZenGradientGenerator.mjs | 1 - src/browser/base/zen-components/ZenWorkspaces.mjs | 9 ++++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/browser/base/zen-components/ZenGradientGenerator.mjs b/src/browser/base/zen-components/ZenGradientGenerator.mjs index 125c45da7..963f87f76 100644 --- a/src/browser/base/zen-components/ZenGradientGenerator.mjs +++ b/src/browser/base/zen-components/ZenGradientGenerator.mjs @@ -37,7 +37,6 @@ this.initCanvas(); this.initCustomColorInput(); - ZenWorkspaces.addChangeListeners(this.onWorkspaceChange.bind(this)); window.matchMedia('(prefers-color-scheme: dark)').addListener(this.onDarkModeChange.bind(this)); } diff --git a/src/browser/base/zen-components/ZenWorkspaces.mjs b/src/browser/base/zen-components/ZenWorkspaces.mjs index 9aeeeabb7..421f46a8a 100644 --- a/src/browser/base/zen-components/ZenWorkspaces.mjs +++ b/src/browser/base/zen-components/ZenWorkspaces.mjs @@ -1627,7 +1627,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { return tabToSelect; } - async _updateWorkspaceState(window, onInit) { + async _updateWorkspaceState(window, onInit, tabToSelect) { // Update document state document.documentElement.setAttribute('zen-workspace-id', window.uuid); @@ -1639,6 +1639,11 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { gZenUIManager.updateTabsToolbar(); await this._propagateWorkspaceData({ clearCache: false }); + gZenThemePicker.onWorkspaceChange(window); + + await this._animateTabs(window, !onInit && !this._animatingChange); + gBrowser.selectedTab = tabToSelect; + // Notify listeners if (this._changeListeners?.length) { for (const listener of this._changeListeners) { @@ -1646,8 +1651,6 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } } - await this._animateTabs(window, !onInit && !this._animatingChange); - // Reset bookmarks this._invalidateBookmarkContainers(); From 5f7283531f6f46903e154ac8baf5d57964dbc70c Mon Sep 17 00:00:00 2001 From: Jupi <73097618+JSGRD22@users.noreply.github.com> Date: Thu, 13 Feb 2025 21:24:55 +0800 Subject: [PATCH 11/33] Set gfx.canvas.accelerated.cache-size to 256 by default Signed-off-by: Jupi <73097618+JSGRD22@users.noreply.github.com> --- src/browser/app/profile/zen-browser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/app/profile/zen-browser.js b/src/browser/app/profile/zen-browser.js index a61533e60..c13375eb1 100644 --- a/src/browser/app/profile/zen-browser.js +++ b/src/browser/app/profile/zen-browser.js @@ -425,7 +425,7 @@ pref("browser.aboutwelcome.enabled", false); // ---- Experimental settings to try make zen faster pref("gfx.canvas.accelerated.cache-items", 32768); -pref("gfx.canvas.accelerated.cache-size", 4096); +pref("gfx.canvas.accelerated.cache-size", 256); pref("gfx.content.skia-font-cache-size", 80); pref("media.memory_cache_max_size", 1048576); From d6acd4deb8a0b62ced98d6522b4c6b428ca9f19a Mon Sep 17 00:00:00 2001 From: "mr. m" Date: Thu, 13 Feb 2025 16:29:34 +0100 Subject: [PATCH 12/33] Fixed switching workspaces --- src/browser/base/content/ZenUIManager.mjs | 2 +- .../base/content/zen-styles/zen-workspaces.css | 1 + .../base/zen-components/ZenWorkspaces.mjs | 13 +++++++++---- .../tabbrowser/content/tabbrowser-js.patch | 16 +++++++++++----- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/browser/base/content/ZenUIManager.mjs b/src/browser/base/content/ZenUIManager.mjs index ca3354728..ca1aaecd3 100644 --- a/src/browser/base/content/ZenUIManager.mjs +++ b/src/browser/base/content/ZenUIManager.mjs @@ -414,7 +414,7 @@ var gZenVerticalTabsManager = { gBrowser.tabContainer.setAttribute('orient', isVerticalTabs ? 'vertical' : 'horizontal'); gBrowser.tabContainer.arrowScrollbox.setAttribute('orient', isVerticalTabs ? 'vertical' : 'horizontal'); // on purpose, we set the orient to horizontal, because the arrowScrollbox is vertical - gBrowser.tabContainer.arrowScrollbox.scrollbox.setAttribute('orient', isVerticalTabs ? 'horizontal' : 'vertical'); + gBrowser.tabContainer.arrowScrollbox.scrollbox.setAttribute('orient', (isVerticalTabs && ZenWorkspaces.workspaceEnabled) ? 'horizontal' : 'vertical'); const buttonsTarget = document.getElementById('zen-sidebar-top-buttons-customization-target'); if (isRightSide) { diff --git a/src/browser/base/content/zen-styles/zen-workspaces.css b/src/browser/base/content/zen-styles/zen-workspaces.css index 32f2a7c9a..288032e8b 100644 --- a/src/browser/base/content/zen-styles/zen-workspaces.css +++ b/src/browser/base/content/zen-styles/zen-workspaces.css @@ -457,6 +457,7 @@ max-height: var(--zen-workspace-indicator-height); min-height: var(--zen-workspace-indicator-height); gap: 12px; + white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex-direction: row !important; diff --git a/src/browser/base/zen-components/ZenWorkspaces.mjs b/src/browser/base/zen-components/ZenWorkspaces.mjs index 421f46a8a..65c0a824d 100644 --- a/src/browser/base/zen-components/ZenWorkspaces.mjs +++ b/src/browser/base/zen-components/ZenWorkspaces.mjs @@ -1500,7 +1500,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } } - async _animateTabs(newWorkspace, shouldAnimate) { + async _animateTabs(newWorkspace, shouldAnimate, tabToSelect = null) { this._animatingChange = true; const animations = []; const workspaces = await this._workspaces(); @@ -1534,11 +1534,18 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } if (offset === 0) { element.setAttribute('active', 'true'); + if (tabToSelect) { + gBrowser.selectedTab = tabToSelect; + tabToSelect._visuallySelected = false; + } } else { element.removeAttribute('active'); } } await Promise.all(animations); + if (tabToSelect) { + tabToSelect._visuallySelected = false; + } this._animatingChange = false; } @@ -1618,7 +1625,6 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { tabToSelect = newTab; } tabToSelect._visuallySelected = true; - this._lastSelectedWorkspaceTabs[window.uuid] = tabToSelect; // Always make sure we always unselect the tab from the old workspace if (currentSelectedTab && currentSelectedTab !== tabToSelect) { @@ -1641,8 +1647,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { gZenThemePicker.onWorkspaceChange(window); - await this._animateTabs(window, !onInit && !this._animatingChange); - gBrowser.selectedTab = tabToSelect; + await this._animateTabs(window, !onInit && !this._animatingChange, tabToSelect); // Notify listeners if (this._changeListeners?.length) { diff --git a/src/browser/components/tabbrowser/content/tabbrowser-js.patch b/src/browser/components/tabbrowser/content/tabbrowser-js.patch index e5ba04639..3863cf041 100644 --- a/src/browser/components/tabbrowser/content/tabbrowser-js.patch +++ b/src/browser/components/tabbrowser/content/tabbrowser-js.patch @@ -1,5 +1,5 @@ diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js -index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..c90119b4b248887fd8612beb9aac83c6eeb57088 100644 +index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..364bd46b5244c13139dec5a7f9401dbef2582976 100644 --- a/browser/components/tabbrowser/content/tabbrowser.js +++ b/browser/components/tabbrowser/content/tabbrowser.js @@ -406,11 +406,39 @@ @@ -57,8 +57,12 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..c90119b4b248887fd8612beb9aac83c6 } aTab.setAttribute("pinned", "true"); this._updateTabBarForPinnedTabs(); -@@ -831,7 +859,7 @@ - this.tabContainer.arrowScrollbox.prepend(aTab); +@@ -828,10 +856,10 @@ + // the moving of a tab from the vertical pinned tabs container + // and back into arrowscrollbox. + aTab.removeAttribute("pinned"); +- this.tabContainer.arrowScrollbox.prepend(aTab); ++ ZenWorkspaces.activeWorkspaceStrip.prepend(aTab); }); } else { - this.moveTabTo(aTab, this.pinnedTabCount - 1, { @@ -112,11 +116,13 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..c90119b4b248887fd8612beb9aac83c6 aTab.linkedPanel = uniqueId; // Inject the into the DOM if necessary. -@@ -2447,7 +2484,7 @@ +@@ -2446,8 +2483,8 @@ + // If we transitioned from one browser to two browsers, we need to set // hasSiblings=false on both the existing browser and the new browser. if (this.tabs.length == 2) { - this.tabs[0].linkedBrowser.browsingContext.hasSiblings = true; +- this.tabs[0].linkedBrowser.browsingContext.hasSiblings = true; - this.tabs[1].linkedBrowser.browsingContext.hasSiblings = true; ++ if (this.tabs[0].linkedBrowser.browsingContext) this.tabs[0].linkedBrowser.browsingContext.hasSiblings = true; + if (this.tabs[1].linkedBrowser.browsingContext) this.tabs[1].linkedBrowser.browsingContext.hasSiblings = true; } else { aTab.linkedBrowser.browsingContext.hasSiblings = this.tabs.length > 1; From a5ae4077cfbc88b48ee0068d0a771bbc2968de98 Mon Sep 17 00:00:00 2001 From: "mr. M" Date: Thu, 13 Feb 2025 17:32:33 +0100 Subject: [PATCH 13/33] Refactor workspace tab transformations and update tab selection logic --- src/browser/base/zen-components/ZenWorkspaces.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/browser/base/zen-components/ZenWorkspaces.mjs b/src/browser/base/zen-components/ZenWorkspaces.mjs index 65c0a824d..01da4272b 100644 --- a/src/browser/base/zen-components/ZenWorkspaces.mjs +++ b/src/browser/base/zen-components/ZenWorkspaces.mjs @@ -1544,7 +1544,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } await Promise.all(animations); if (tabToSelect) { - tabToSelect._visuallySelected = false; + tabToSelect._visuallySelected = true; } this._animatingChange = false; } @@ -1592,7 +1592,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } // Show if tab belongs to current workspace - return true; + return tabWorkspaceId === workspaceUuid; } async _handleTabSelection(window, onInit, containerId, workspaces, previousWorkspaceId) { From 31ef8d2ec935161d1e9e6db44c0eeac631e9b4cf Mon Sep 17 00:00:00 2001 From: "mr. M" Date: Thu, 13 Feb 2025 19:17:20 +0100 Subject: [PATCH 14/33] Refactor tab management and update CSS for improved layout and performance --- src/browser/base/content/ZenUIManager.mjs | 7 +++++-- .../content/navigator-toolbox-inc-xhtml.patch | 14 ++++++++------ .../zen-styles/zen-tabs/vertical-tabs.css | 5 ++++- .../base/zen-components/ZenWorkspaces.mjs | 18 ++++++++++-------- 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/browser/base/content/ZenUIManager.mjs b/src/browser/base/content/ZenUIManager.mjs index ca1aaecd3..a20dafdef 100644 --- a/src/browser/base/content/ZenUIManager.mjs +++ b/src/browser/base/content/ZenUIManager.mjs @@ -35,7 +35,7 @@ var gZenUIManager = { updateTabsToolbar() { // Set tabs max-height to the "toolbar-items" height - const tabs = document.getElementById('zen-browser-tabs-wrapper'); + const tabs = this.tabsWrapper; // Remove tabs so we can accurately calculate the height // without them affecting the height of the toolbar for (const tab of gBrowser.tabs) { @@ -414,7 +414,10 @@ var gZenVerticalTabsManager = { gBrowser.tabContainer.setAttribute('orient', isVerticalTabs ? 'vertical' : 'horizontal'); gBrowser.tabContainer.arrowScrollbox.setAttribute('orient', isVerticalTabs ? 'vertical' : 'horizontal'); // on purpose, we set the orient to horizontal, because the arrowScrollbox is vertical - gBrowser.tabContainer.arrowScrollbox.scrollbox.setAttribute('orient', (isVerticalTabs && ZenWorkspaces.workspaceEnabled) ? 'horizontal' : 'vertical'); + gBrowser.tabContainer.arrowScrollbox.scrollbox.setAttribute( + 'orient', + isVerticalTabs && ZenWorkspaces.workspaceEnabled ? 'horizontal' : 'vertical' + ); const buttonsTarget = document.getElementById('zen-sidebar-top-buttons-customization-target'); if (isRightSide) { diff --git a/src/browser/base/content/navigator-toolbox-inc-xhtml.patch b/src/browser/base/content/navigator-toolbox-inc-xhtml.patch index bc2ef52de..0419daa0c 100644 --- a/src/browser/base/content/navigator-toolbox-inc-xhtml.patch +++ b/src/browser/base/content/navigator-toolbox-inc-xhtml.patch @@ -1,5 +1,5 @@ diff --git a/browser/base/content/navigator-toolbox.inc.xhtml b/browser/base/content/navigator-toolbox.inc.xhtml -index a0a382643a2f74b6d789f3641ef300eed202d5e9..340475da315e67b2dd4f93567547cde703a90ee8 100644 +index a0a382643a2f74b6d789f3641ef300eed202d5e9..fd60aceee18e22d40c7d86506408803e3f4ffd45 100644 --- a/browser/base/content/navigator-toolbox.inc.xhtml +++ b/browser/base/content/navigator-toolbox.inc.xhtml @@ -2,7 +2,7 @@ @@ -40,17 +40,18 @@ index a0a382643a2f74b6d789f3641ef300eed202d5e9..340475da315e67b2dd4f93567547cde7 + + + ++ + @@ -83,7 +85,7 @@ index a0a382643a2f74b6d789f3641ef300eed202d5e9..340475da315e67b2dd4f93567547cde7 diff --git a/src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css b/src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css index a5ca41b3f..5efc7354f 100644 --- a/src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css +++ b/src/browser/base/content/zen-styles/zen-tabs/vertical-tabs.css @@ -368,9 +368,12 @@ #zen-browser-tabs-wrapper { min-height: fit-content; overflow-y: auto; - overflow-x: clip !important; /* might break custom css with new design, so let's force it */ height: 100%; scrollbar-width: thin; +} + +#zen-browser-tabs-container { + overflow-x: clip !important; /* might break custom css with new design, so let's force it */ position: relative; } diff --git a/src/browser/base/zen-components/ZenWorkspaces.mjs b/src/browser/base/zen-components/ZenWorkspaces.mjs index 01da4272b..e622626b8 100644 --- a/src/browser/base/zen-components/ZenWorkspaces.mjs +++ b/src/browser/base/zen-components/ZenWorkspaces.mjs @@ -1464,13 +1464,11 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { for (const container of document.querySelectorAll(selector)) { container.style.transform = `translateX(${newTransform + offsetPixels / 2}%)`; container.style.opacity = offsetPixels ? 1 : !newTransform; - } - if (!justMove) { - const pinnedContainerId = '#vertical-pinned-tabs-container '; - const arrowScrollboxId = '#tabbrowser-arrowscrollbox '; - const pinnedContainer = document.querySelector(pinnedContainerId + selector); - const arrowScrollbox = document.querySelector(arrowScrollboxId + selector); - this._updateMarginTopPinnedTabs(arrowScrollbox, pinnedContainer); + if (!offsetPixels && !container.hasAttribute('active')) { + container.style.position = 'fixed'; + } else { + container.style.removeProperty('position'); + } } } } @@ -1513,6 +1511,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { const newTransform = `translateX(${offset}%)`; const isCurrent = offset === 0; if (shouldAnimate) { + element.style.removeProperty('position'); if (isCurrent) { element.style.opacity = 1; } @@ -1534,7 +1533,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } if (offset === 0) { element.setAttribute('active', 'true'); - if (tabToSelect) { + if (tabToSelect != gBrowser.selectedTab) { gBrowser.selectedTab = tabToSelect; tabToSelect._visuallySelected = false; } @@ -1647,7 +1646,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { gZenThemePicker.onWorkspaceChange(window); + document.getElementById('zen-browser-tabs-wrapper').style.scrollbarWidth = 'none'; await this._animateTabs(window, !onInit && !this._animatingChange, tabToSelect); + await this._organizeWorkspaceStripLocations(window, true); + document.getElementById('zen-browser-tabs-wrapper').style.scrollbarWidth = ''; // Notify listeners if (this._changeListeners?.length) { From 855c36280ba34c34b97fbabef6f1af1fc8f527ff Mon Sep 17 00:00:00 2001 From: "mr. M" Date: Thu, 13 Feb 2025 19:36:00 +0100 Subject: [PATCH 15/33] Refactor tab overflow detection and adjust workspace initialization logic --- src/browser/base/content/ZenStartup.mjs | 4 ++-- src/browser/base/zen-components/ZenWorkspaces.mjs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/browser/base/content/ZenStartup.mjs b/src/browser/base/content/ZenStartup.mjs index a09e51f47..e25539c50 100644 --- a/src/browser/base/content/ZenStartup.mjs +++ b/src/browser/base/content/ZenStartup.mjs @@ -94,8 +94,8 @@ // Detect overflow and underflow const observer = new ResizeObserver((_) => { const tabContainer = gBrowser.tabContainer; - const isVertical = tabContainer.getAttribute('orient') === 'vertical'; - let contentSize = tabsWrapper.getBoundingClientRect()[isVertical ? 'height' : 'width']; + // const isVertical = tabContainer.getAttribute('orient') === 'vertical'; + // let contentSize = tabsWrapper.getBoundingClientRect()[isVertical ? 'height' : 'width']; // NOTE: This should be contentSize > scrollClientSize, but due // to how Gecko internally rounds in those cases, we allow for some // minor differences (the internal Gecko layout size is 1/60th of a diff --git a/src/browser/base/zen-components/ZenWorkspaces.mjs b/src/browser/base/zen-components/ZenWorkspaces.mjs index e622626b8..072f7494b 100644 --- a/src/browser/base/zen-components/ZenWorkspaces.mjs +++ b/src/browser/base/zen-components/ZenWorkspaces.mjs @@ -526,7 +526,6 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { this.activeWorkspace = activeWorkspace?.uuid; } } - await this.initializeTabsStripSections(); try { if (activeWorkspace) { window.gZenThemePicker = new ZenThemePicker(); @@ -535,6 +534,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } catch (e) { console.error('ZenWorkspaces: Error initializing theme picker', e); } + await this.initializeTabsStripSections(); } } From 48879fb6a087060ffa879c6a0960161f519cf9bc Mon Sep 17 00:00:00 2001 From: "mr. M" Date: Thu, 13 Feb 2025 21:15:55 +0100 Subject: [PATCH 16/33] Enhance workspace tab initialization and update tab toolbar on load --- src/browser/base/content/ZenUIManager.mjs | 1 + src/browser/base/zen-components/ZenWorkspaces.mjs | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/browser/base/content/ZenUIManager.mjs b/src/browser/base/content/ZenUIManager.mjs index a20dafdef..c4cb657e7 100644 --- a/src/browser/base/content/ZenUIManager.mjs +++ b/src/browser/base/content/ZenUIManager.mjs @@ -27,6 +27,7 @@ var gZenUIManager = { SessionStore.promiseAllWindowsRestored.then(() => { this._hasLoadedDOM = true; + this.updateTabsToolbar(); }); window.addEventListener('TabClose', this.onTabClose.bind(this)); diff --git a/src/browser/base/zen-components/ZenWorkspaces.mjs b/src/browser/base/zen-components/ZenWorkspaces.mjs index 072f7494b..ec56db764 100644 --- a/src/browser/base/zen-components/ZenWorkspaces.mjs +++ b/src/browser/base/zen-components/ZenWorkspaces.mjs @@ -148,7 +148,8 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { async initializeTabsStripSections() { const perifery = document.getElementById('tabbrowser-arrowscrollbox-periphery'); const tabs = gBrowser.tabContainer.allTabs.filter((tab) => !tab.pinned); - for (const workspace of (await this._workspaces()).workspaces) { + const workspaces = await this._workspaces(); + for (const workspace of workspaces.workspaces) { this._createWorkspaceTabsSection(workspace, tabs, perifery); } if (tabs.length) { @@ -164,6 +165,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { perifery.setAttribute('hidden', 'true'); this._hasInitializedTabsStrip = true; this.registerPinnedResizeObserver(); + this._fixIndicatorsNames(workspaces); } _createWorkspaceSection(workspace) { @@ -526,6 +528,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { this.activeWorkspace = activeWorkspace?.uuid; } } + await this.initializeTabsStripSections(); try { if (activeWorkspace) { window.gZenThemePicker = new ZenThemePicker(); @@ -534,7 +537,6 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } catch (e) { console.error('ZenWorkspaces: Error initializing theme picker', e); } - await this.initializeTabsStripSections(); } } @@ -1740,7 +1742,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } onPinnedTabsResize(entries) { - if (!this.workspaceEnabled) { + if (!this.workspaceEnabled || !this._hasInitializedTabsStrip) { return; } for (const entry of entries) { From 07ede1b96bd6895cd4960978a5ba3a54cb68e9fa Mon Sep 17 00:00:00 2001 From: "mr. M" Date: Thu, 13 Feb 2025 22:02:17 +0100 Subject: [PATCH 17/33] Add Windows acrylic support and enhance toolbar transparency styles --- src/browser/app/profile/zen-browser.js | 4 ++++ src/browser/base/content/zen-styles/zen-theme.css | 10 +++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/browser/app/profile/zen-browser.js b/src/browser/app/profile/zen-browser.js index a61533e60..bbc3d7069 100644 --- a/src/browser/app/profile/zen-browser.js +++ b/src/browser/app/profile/zen-browser.js @@ -127,6 +127,10 @@ pref('zen.view.experimental-rounded-view', false); pref('zen.view.experimental-rounded-view', true); #endif +#ifdef XP_WIN +pref('zen.widget.windows.acrylic', true); +#endif + // Glance pref('zen.glance.enabled', true); pref('zen.glance.hold-duration', 300); // in ms diff --git a/src/browser/base/content/zen-styles/zen-theme.css b/src/browser/base/content/zen-styles/zen-theme.css index 480f65c52..f5482f7ac 100644 --- a/src/browser/base/content/zen-styles/zen-theme.css +++ b/src/browser/base/content/zen-styles/zen-theme.css @@ -162,9 +162,13 @@ @media (-moz-windows-mica) or (-moz-platform: macos) { background: transparent; --zen-themed-toolbar-bg-transparency: 0; - --zen-themed-toolbar-bg-transparent: light-dark( - rgba(255, 255, 255, var(--zen-themed-toolbar-bg-transparency)), - rgba(0, 0, 0, var(--zen-themed-toolbar-bg-transparency)) + @media (-moz-bool-pref: 'zen.widget.windows.acrylic') { + --zen-themed-toolbar-bg-transparency: 15%; + } + --zen-themed-toolbar-bg-transparent: color-mix( + in srgb, + var(--zen-themed-toolbar-bg) calc(100% - var(--zen-themed-toolbar-bg-transparency)), + transparent var(--zen-themed-toolbar-bg-transparency) ); } From 869c2eb8b295924bd1d2cdae82f6135c5d5c4052 Mon Sep 17 00:00:00 2001 From: "mr. M" Date: Fri, 14 Feb 2025 11:29:25 +0100 Subject: [PATCH 18/33] Refactor pinned tab management and improve event handling for workspace initialization --- src/browser/base/content/ZenUIManager.mjs | 4 +- .../zen-components/ZenPinnedTabManager.mjs | 53 +++------------- .../zen-components/ZenPinnedTabsStorage.mjs | 1 - .../base/zen-components/ZenWorkspaces.mjs | 61 +++++++++++++------ .../sessionstore/SessionStore-sys-mjs.patch | 18 +++++- .../tabbrowser/content/tabbrowser-js.patch | 27 +++++--- .../tabbrowser/content/tabs-js.patch | 26 +++++--- 7 files changed, 102 insertions(+), 88 deletions(-) diff --git a/src/browser/base/content/ZenUIManager.mjs b/src/browser/base/content/ZenUIManager.mjs index c4cb657e7..9e83c5a32 100644 --- a/src/browser/base/content/ZenUIManager.mjs +++ b/src/browser/base/content/ZenUIManager.mjs @@ -241,9 +241,7 @@ var gZenVerticalTabsManager = { window.addEventListener('customizationstarting', this._preCustomize.bind(this)); window.addEventListener('aftercustomization', this._postCustomize.bind(this)); - window.addEventListener('DOMContentLoaded', updateEvent, { once: true }); - - const tabs = document.getElementById('tabbrowser-tabs'); + window.addEventListener('MozAfterPaint', updateEvent, { once: true }); if (!this.isWindowsStyledButtons) { document.documentElement.setAttribute('zen-window-buttons-reversed', true); diff --git a/src/browser/base/zen-components/ZenPinnedTabManager.mjs b/src/browser/base/zen-components/ZenPinnedTabManager.mjs index a3487fee7..a046f472a 100644 --- a/src/browser/base/zen-components/ZenPinnedTabManager.mjs +++ b/src/browser/base/zen-components/ZenPinnedTabManager.mjs @@ -69,7 +69,9 @@ return; } - await this._refreshPinnedTabs(newWorkspace, { init: onInit }); + if (onInit) { + await this._refreshPinnedTabs(newWorkspace, { init: onInit }); + } } log(message) { @@ -152,7 +154,7 @@ const pinsToCreate = new Set(pins.map((p) => p.uuid)); // First pass: identify existing tabs and remove those without pins - for (let tab of gBrowser.tabs) { + for (let tab of ZenWorkspaces.allStoredTabs) { const pinId = tab.getAttribute('zen-pin-id'); if (!pinId) { continue; @@ -178,10 +180,6 @@ continue; // Skip pins that already have tabs } - if (!this._shouldShowPin(pin, currentWorkspace, workspaces)) { - continue; // Skip pins not relevant to current workspace - } - let params = { skipAnimation: true, allowInheritPrincipal: false, @@ -234,6 +232,12 @@ this.log(`Created new pinned tab for pin ${pin.uuid} (isEssential: ${pin.isEssential})`); gBrowser.pinTab(newTab); + if (!pin.isEssential) { + const contaienr = document.querySelector( + `#vertical-pinned-tabs-container .zen-workspace-tabs-section[zen-workspace-id="${pin.workspaceUuid}"]` + ); + contaienr.insertBefore(newTab, contaienr.lastChild); + } newTab.initialize(); } @@ -246,43 +250,6 @@ gBrowser._updateTabBarForPinnedTabs(); } - _shouldShowPin(pin, currentWorkspace, workspaces) { - const isEssential = pin.isEssential; - const pinWorkspaceUuid = pin.workspaceUuid; - const pinContextId = pin.containerTabId ? pin.containerTabId.toString() : '0'; - const workspaceContextId = currentWorkspace.containerTabId?.toString() || '0'; - const containerSpecificEssentials = ZenWorkspaces.containerSpecificEssentials; - - // Handle essential pins - if (isEssential) { - if (!containerSpecificEssentials) { - return true; // Show all essential pins when containerSpecificEssentials is false - } - - if (workspaceContextId !== '0') { - // In workspaces with default container: Show essentials that match the container - return pinContextId === workspaceContextId; - } else { - // In workspaces without a default container: Show essentials that aren't in container-specific workspaces - // or have userContextId="0" or no userContextId - return ( - !pinContextId || - pinContextId === '0' || - !workspaces.workspaces.some((workspace) => workspace.containerTabId === parseInt(pinContextId, 10)) - ); - } - } - - // For non-essential pins - if (!pinWorkspaceUuid) { - // Pins without a workspace belong to all workspaces (if that's your desired behavior) - return true; - } - - // Show if pin belongs to current workspace - return pinWorkspaceUuid === currentWorkspace.uuid; - } - _onPinnedTabEvent(action, event) { if (!this.enabled) return; const tab = event.target; diff --git a/src/browser/base/zen-components/ZenPinnedTabsStorage.mjs b/src/browser/base/zen-components/ZenPinnedTabsStorage.mjs index 7e5ab6017..b47850b4e 100644 --- a/src/browser/base/zen-components/ZenPinnedTabsStorage.mjs +++ b/src/browser/base/zen-components/ZenPinnedTabsStorage.mjs @@ -46,7 +46,6 @@ var ZenPinnedTabsStorage = { CREATE INDEX IF NOT EXISTS idx_zen_pins_changes_uuid ON zen_pins_changes(uuid) `); - await SessionStore.promiseInitialized; this._resolveInitialized(); }); }, diff --git a/src/browser/base/zen-components/ZenWorkspaces.mjs b/src/browser/base/zen-components/ZenWorkspaces.mjs index ec56db764..bd698f616 100644 --- a/src/browser/base/zen-components/ZenWorkspaces.mjs +++ b/src/browser/base/zen-components/ZenWorkspaces.mjs @@ -28,13 +28,17 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { this._resolvePinnedInitialized = resolve; }); + promiseSectionsInitialized = new Promise((resolve) => { + this._resolveSectionsInitialized = resolve; + }); + workspaceIndicatorXUL = ` `; async waitForPromises() { - await Promise.all([this.promiseDBInitialized, this.promisePinnedInitialized, SessionStore.promiseAllWindowsRestored]); + await Promise.all([this.promiseDBInitialized, this.promisePinnedInitialized]); } async init() { @@ -75,18 +79,21 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { ); ChromeUtils.defineLazyGetter(this, 'tabContainer', () => document.getElementById('tabbrowser-tabs')); this._activeWorkspace = Services.prefs.getStringPref('zen.workspaces.active', ''); - this._delayedStartup(); + await SessionStore.promiseInitialized; + if (!this._hasInitializedTabsStrip) { + await this.delayedStartup(); + } + await this.promiseSectionsInitialized; + window.addEventListener('MozAfterPaint', async () => { + await SessionStore.promiseAllWindowsRestored; + await this.afterLoadInit(); + }, { once: true }); } - async _delayedStartup() { - if (!this.workspaceEnabled) { - return; - } - this._pinnedTabsResizeObserver = new ResizeObserver(this.onPinnedTabsResize.bind(this)); - await this.waitForPromises(); - await this.initializeWorkspaces(); + async afterLoadInit() { console.info('ZenWorkspaces: ZenWorkspaces initialized'); + await this.initializeWorkspaces(); if (Services.prefs.getBoolPref('zen.workspaces.swipe-actions', false) && this.workspaceEnabled) { this.initializeGestureHandlers(); this.initializeWorkspaceNavigation(); @@ -103,6 +110,16 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { ); } + async delayedStartup() { + if (!this.workspaceEnabled) { + return; + } + this._pinnedTabsResizeObserver = new ResizeObserver(this.onPinnedTabsResize.bind(this)); + await this.waitForPromises(); + await this.initializeTabsStripSections(); + this._resolveSectionsInitialized(); + } + registerPinnedResizeObserver() { if (!this._hasInitializedTabsStrip) { return; @@ -117,7 +134,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } get activeWorkspaceStrip() { - if (!this.workspaceEnabled || !this._hasInitializedTabsStrip) { + if (!this._hasInitializedTabsStrip) { return gBrowser.tabContainer.arrowScrollbox; } const activeWorkspace = this.activeWorkspace; @@ -147,7 +164,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { async initializeTabsStripSections() { const perifery = document.getElementById('tabbrowser-arrowscrollbox-periphery'); - const tabs = gBrowser.tabContainer.allTabs.filter((tab) => !tab.pinned); + const tabs = gBrowser.tabContainer.allTabs; const workspaces = await this._workspaces(); for (const workspace of workspaces.workspaces) { this._createWorkspaceTabsSection(workspace, tabs, perifery); @@ -156,11 +173,17 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { const defaultSelectedContainer = document.querySelector( `#tabbrowser-arrowscrollbox .zen-workspace-tabs-section[zen-workspace-id="${this.activeWorkspace}"]` ); + const pinnedContainer = document.querySelector( + `#vertical-pinned-tabs-container .zen-workspace-tabs-section[zen-workspace-id="${this.activeWorkspace}"]` + ); for (const tab of tabs) { + if (tab.pinned) { + pinnedContainer.insertBefore(tab, pinnedContainer.lastChild); + continue; + } // before to the last child (perifery) defaultSelectedContainer.insertBefore(tab, defaultSelectedContainer.lastChild); } - this.tabContainer._invalidateCachedTabs(); } perifery.setAttribute('hidden', 'true'); this._hasInitializedTabsStrip = true; @@ -210,7 +233,6 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { section.appendChild(tab); } } - this.tabContainer._invalidateCachedTabs(); } initializeWorkspaceNavigation() { @@ -512,7 +534,6 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { await this.workspaceBookmarks(); window.addEventListener('TabBrowserInserted', this.onTabBrowserInserted.bind(this)); window.addEventListener('TabOpen', this.updateTabsContainers.bind(this)); - window.addEventListener('TabClose', this.updateTabsContainers.bind(this)); let workspaces = await this._workspaces(); let activeWorkspace = null; if (workspaces.workspaces.length === 0) { @@ -528,11 +549,11 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { this.activeWorkspace = activeWorkspace?.uuid; } } - await this.initializeTabsStripSections(); try { if (activeWorkspace) { window.gZenThemePicker = new ZenThemePicker(); await this.changeWorkspace(activeWorkspace, { onInit: true }); + gBrowser.tabContainer._positionPinnedTabs(); } } catch (e) { console.error('ZenWorkspaces: Error initializing theme picker', e); @@ -1335,8 +1356,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { let tab = gZenUIManager.openAndChangeToTab(BROWSER_NEW_TAB_URL); if (window.uuid) { - this.moveTabToWorkspace(tab, window.uuid); + tab.setAttribute("zen-workspace-id", window.uuid) } + + return tab; } async saveWorkspaceFromCreate() { @@ -1401,8 +1424,6 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { if (!this.workspaceEnabled || this._inChangingWorkspace) { return; } - - await SessionStore.promiseInitialized; this._inChangingWorkspace = true; try { await this._performWorkspaceChange(window, ...args); @@ -1742,7 +1763,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } onPinnedTabsResize(entries) { - if (!this.workspaceEnabled || !this._hasInitializedTabsStrip) { + if (!this._hasInitializedTabsStrip) { return; } for (const entry of entries) { @@ -1790,7 +1811,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } // Switch workspace if needed - if (workspaceID && workspaceID !== activeWorkspace.uuid) { + if (workspaceID && workspaceID !== activeWorkspace.uuid && parent.ZenWorkspaces._hasInitializedTabsStrip) { await parent.ZenWorkspaces.changeWorkspace({ uuid: workspaceID }); } } diff --git a/src/browser/components/sessionstore/SessionStore-sys-mjs.patch b/src/browser/components/sessionstore/SessionStore-sys-mjs.patch index 2c7b2688f..c00a2b8e4 100644 --- a/src/browser/components/sessionstore/SessionStore-sys-mjs.patch +++ b/src/browser/components/sessionstore/SessionStore-sys-mjs.patch @@ -1,8 +1,20 @@ diff --git a/browser/components/sessionstore/SessionStore.sys.mjs b/browser/components/sessionstore/SessionStore.sys.mjs -index 908743177d9f95e2e6549c689e7a493ca8668701..b452d7dfc93f6171f8a65668e052a37638f1f6c3 100644 +index 908743177d9f95e2e6549c689e7a493ca8668701..2dd53f5fdbffb21dfdc8bf68a6771d4ac0acd8be 100644 --- a/browser/components/sessionstore/SessionStore.sys.mjs +++ b/browser/components/sessionstore/SessionStore.sys.mjs -@@ -3848,6 +3848,7 @@ var SessionStoreInternal = { +@@ -2174,9 +2174,10 @@ var SessionStoreInternal = { + TelemetryStopwatch.finish( + "FX_SESSION_RESTORE_STARTUP_ONLOAD_INITIAL_WINDOW_MS" + ); +- ++ aWindow.ZenWorkspaces.delayedStartup().then(() => { + // Let everyone know we're done. + this._deferredInitialized.resolve(); ++ }); + } + }) + .catch(ex => { +@@ -3848,6 +3849,7 @@ var SessionStoreInternal = { aWindow.gBrowser.selectedTab = newTab; } @@ -10,7 +22,7 @@ index 908743177d9f95e2e6549c689e7a493ca8668701..b452d7dfc93f6171f8a65668e052a376 // Restore the state into the new tab. this.restoreTab(newTab, tabState, { restoreImmediately: aRestoreImmediately, -@@ -5315,7 +5316,7 @@ var SessionStoreInternal = { +@@ -5315,7 +5317,7 @@ var SessionStoreInternal = { } let tabbrowser = aWindow.gBrowser; diff --git a/src/browser/components/tabbrowser/content/tabbrowser-js.patch b/src/browser/components/tabbrowser/content/tabbrowser-js.patch index 3863cf041..5511152c7 100644 --- a/src/browser/components/tabbrowser/content/tabbrowser-js.patch +++ b/src/browser/components/tabbrowser/content/tabbrowser-js.patch @@ -1,5 +1,5 @@ diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js -index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..364bd46b5244c13139dec5a7f9401dbef2582976 100644 +index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..bdebb5eeb16c1c7b9fd0d0266d5fa7b5e12e95a1 100644 --- a/browser/components/tabbrowser/content/tabbrowser.js +++ b/browser/components/tabbrowser/content/tabbrowser.js @@ -406,11 +406,39 @@ @@ -321,7 +321,16 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..364bd46b5244c13139dec5a7f9401dbe if (closeWindow) { // We've already called beforeunload on all the relevant tabs if we get here, -@@ -5465,10 +5558,10 @@ +@@ -4812,6 +4905,8 @@ + this.tabs[i]._tPos = i; + } + ++ ZenWorkspaces.updateTabsContainers(); ++ + if (!this._windowIsClosing) { + if (wasPinned) { + this.tabContainer._positionPinnedTabs(); +@@ -5465,10 +5560,10 @@ SessionStore.deleteCustomTabValue(aTab, "hiddenBy"); } @@ -334,7 +343,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..364bd46b5244c13139dec5a7f9401dbe aTab.selected || aTab.closing || // Tabs that are sharing the screen, microphone or camera cannot be hidden. -@@ -5706,9 +5799,9 @@ +@@ -5706,9 +5801,9 @@ // Don't allow mixing pinned and unpinned tabs. if (aTab.pinned) { @@ -346,7 +355,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..364bd46b5244c13139dec5a7f9401dbe } if (aTab._tPos == aIndex) { return; -@@ -5727,6 +5820,9 @@ +@@ -5727,6 +5822,9 @@ this.tabContainer.insertBefore(aTab, neighbor); } }); @@ -356,7 +365,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..364bd46b5244c13139dec5a7f9401dbe } moveTabToGroup(aTab, aGroup) { -@@ -5802,7 +5898,7 @@ +@@ -5802,7 +5900,7 @@ createLazyBrowser, }; @@ -365,7 +374,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..364bd46b5244c13139dec5a7f9401dbe if (aIndex < numPinned || (aTab.pinned && aIndex == numPinned)) { params.pinned = true; } -@@ -7443,6 +7539,7 @@ +@@ -7443,6 +7541,7 @@ aWebProgress.isTopLevel ) { this.mTab.setAttribute("busy", "true"); @@ -373,7 +382,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..364bd46b5244c13139dec5a7f9401dbe gBrowser._tabAttrModified(this.mTab, ["busy"]); this.mTab._notselectedsinceload = !this.mTab.selected; gBrowser.syncThrobberAnimations(this.mTab); -@@ -8411,7 +8508,7 @@ var TabContextMenu = { +@@ -8411,7 +8510,7 @@ var TabContextMenu = { ); contextUnpinSelectedTabs.hidden = !this.contextTab.pinned || !multiselectionContext; @@ -382,7 +391,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..364bd46b5244c13139dec5a7f9401dbe // Move Tab items let contextMoveTabOptions = document.getElementById( "context_moveTabOptions" -@@ -8444,7 +8541,7 @@ var TabContextMenu = { +@@ -8444,7 +8543,7 @@ var TabContextMenu = { let contextMoveTabToStart = document.getElementById("context_moveToStart"); let isFirstTab = tabsToMove[0] == visibleTabs[0] || @@ -391,7 +400,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..364bd46b5244c13139dec5a7f9401dbe contextMoveTabToStart.disabled = isFirstTab && allSelectedTabsAdjacent; document.getElementById("context_openTabInWindow").disabled = -@@ -8677,6 +8774,7 @@ var TabContextMenu = { +@@ -8677,6 +8776,7 @@ var TabContextMenu = { if (this.contextTab.multiselected) { gBrowser.removeMultiSelectedTabs(); } else { diff --git a/src/browser/components/tabbrowser/content/tabs-js.patch b/src/browser/components/tabbrowser/content/tabs-js.patch index dfafb0b6c..acadf284f 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..f7866af6f5b72e2704a87148300a391b20e112db 100644 +index 8aeb244ffca9f48661805f5b7d860b5896055562..0bbce48745d85188ffc0ed9758ee4978bb3c8e59 100644 --- a/browser/components/tabbrowser/content/tabs.js +++ b/browser/components/tabbrowser/content/tabs.js @@ -94,7 +94,7 @@ @@ -293,7 +293,15 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..f7866af6f5b72e2704a87148300a391b let absPositionHorizontalTabs = this.overflowing && tabs.length > numPinned && numPinned > 0; -@@ -2074,7 +2099,7 @@ +@@ -2003,6 +2028,7 @@ + if (this.verticalMode) { + this._updateVerticalPinnedTabs(); + } else if (absPositionHorizontalTabs) { ++ return; + let layoutData = this._pinnedTabsLayoutCache; + let uiDensity = document.documentElement.getAttribute("uidensity"); + if (!layoutData || layoutData.uiDensity != uiDensity) { +@@ -2074,7 +2100,7 @@ return; } @@ -302,7 +310,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..f7866af6f5b72e2704a87148300a391b let directionX = screenX > dragData.animLastScreenX; let directionY = screenY > dragData.animLastScreenY; -@@ -2257,9 +2282,9 @@ +@@ -2257,9 +2283,9 @@ } let pinned = draggedTab.pinned; @@ -315,7 +323,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..f7866af6f5b72e2704a87148300a391b pinned ? numPinned : undefined ); -@@ -2502,8 +2527,9 @@ +@@ -2502,8 +2528,9 @@ ); } @@ -327,7 +335,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..f7866af6f5b72e2704a87148300a391b return; } -@@ -2668,9 +2694,9 @@ +@@ -2668,9 +2695,9 @@ function newIndex(aTab, index) { // Don't allow mixing pinned and unpinned tabs. if (aTab.pinned) { @@ -339,7 +347,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..f7866af6f5b72e2704a87148300a391b } } -@@ -2754,7 +2780,7 @@ +@@ -2754,7 +2781,7 @@ } _notifyBackgroundTab(aTab) { @@ -348,7 +356,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..f7866af6f5b72e2704a87148300a391b return; } -@@ -2772,12 +2798,14 @@ +@@ -2772,12 +2799,14 @@ selectedTab = { left: selectedTab.left, right: selectedTab.right, @@ -364,7 +372,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..f7866af6f5b72e2704a87148300a391b selectedTab, ]; }) -@@ -2794,8 +2822,11 @@ +@@ -2794,8 +2823,11 @@ delete this._lastTabToScrollIntoView; // Is the new tab already completely visible? if ( @@ -378,7 +386,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..f7866af6f5b72e2704a87148300a391b ) { return; } -@@ -2803,21 +2834,29 @@ +@@ -2803,21 +2835,29 @@ if (this.arrowScrollbox.smoothScroll) { // Can we make both the new tab and the selected tab completely visible? if ( From 46ff0020bb74e4cb7f40f0a5a0549b5ccf89afc7 Mon Sep 17 00:00:00 2001 From: "mr. M" Date: Fri, 14 Feb 2025 11:32:40 +0100 Subject: [PATCH 19/33] Format event listener and improve attribute setting for workspace tabs --- src/browser/base/zen-components/ZenWorkspaces.mjs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/browser/base/zen-components/ZenWorkspaces.mjs b/src/browser/base/zen-components/ZenWorkspaces.mjs index bd698f616..4a0cbfea6 100644 --- a/src/browser/base/zen-components/ZenWorkspaces.mjs +++ b/src/browser/base/zen-components/ZenWorkspaces.mjs @@ -84,10 +84,14 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { await this.delayedStartup(); } await this.promiseSectionsInitialized; - window.addEventListener('MozAfterPaint', async () => { - await SessionStore.promiseAllWindowsRestored; - await this.afterLoadInit(); - }, { once: true }); + window.addEventListener( + 'MozAfterPaint', + async () => { + await SessionStore.promiseAllWindowsRestored; + await this.afterLoadInit(); + }, + { once: true } + ); } async afterLoadInit() { @@ -1356,7 +1360,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { let tab = gZenUIManager.openAndChangeToTab(BROWSER_NEW_TAB_URL); if (window.uuid) { - tab.setAttribute("zen-workspace-id", window.uuid) + tab.setAttribute('zen-workspace-id', window.uuid); } return tab; From c27a26eee4d1308b67bfaa080df1636267efc855 Mon Sep 17 00:00:00 2001 From: "mr. M" Date: Fri, 14 Feb 2025 11:38:00 +0100 Subject: [PATCH 20/33] Rename 'zen-browser-tabs-wrapper' to 'zen-tabs-wrapper' across multiple files for consistency --- src/browser/base/content/ZenStartup.mjs | 2 +- src/browser/base/content/ZenUIManager.mjs | 2 +- src/browser/base/content/navigator-toolbox-inc-xhtml.patch | 4 ++-- src/browser/base/content/navigator-toolbox-js.patch | 6 +++--- .../base/content/zen-styles/zen-tabs/vertical-tabs.css | 2 +- src/browser/base/zen-components/ZenPinnedTabManager.mjs | 2 +- src/browser/base/zen-components/ZenWorkspaces.mjs | 4 ++-- src/browser/components/tabbrowser/content/tabs-js.patch | 4 ++-- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/browser/base/content/ZenStartup.mjs b/src/browser/base/content/ZenStartup.mjs index e25539c50..c4dcd6817 100644 --- a/src/browser/base/content/ZenStartup.mjs +++ b/src/browser/base/content/ZenStartup.mjs @@ -85,7 +85,7 @@ _initSidebarScrolling() { // Disable smooth scroll const canSmoothScroll = Services.prefs.getBoolPref('zen.startup.smooth-scroll-in-tabs', false); - const tabsWrapper = document.getElementById('zen-browser-tabs-wrapper'); + const tabsWrapper = document.getElementById('zen-tabs-wrapper'); gBrowser.tabContainer.addEventListener('wheel', (event) => { if (canSmoothScroll) return; event.preventDefault(); // Prevent the smooth scroll behavior diff --git a/src/browser/base/content/ZenUIManager.mjs b/src/browser/base/content/ZenUIManager.mjs index 9e83c5a32..e9f32b5b7 100644 --- a/src/browser/base/content/ZenUIManager.mjs +++ b/src/browser/base/content/ZenUIManager.mjs @@ -63,7 +63,7 @@ var gZenUIManager = { if (this._tabsWrapper) { return this._tabsWrapper; } - this._tabsWrapper = document.getElementById('zen-browser-tabs-wrapper'); + this._tabsWrapper = document.getElementById('zen-tabs-wrapper'); return this._tabsWrapper; }, diff --git a/src/browser/base/content/navigator-toolbox-inc-xhtml.patch b/src/browser/base/content/navigator-toolbox-inc-xhtml.patch index 0419daa0c..0f75a3ff5 100644 --- a/src/browser/base/content/navigator-toolbox-inc-xhtml.patch +++ b/src/browser/base/content/navigator-toolbox-inc-xhtml.patch @@ -1,5 +1,5 @@ diff --git a/browser/base/content/navigator-toolbox.inc.xhtml b/browser/base/content/navigator-toolbox.inc.xhtml -index a0a382643a2f74b6d789f3641ef300eed202d5e9..fd60aceee18e22d40c7d86506408803e3f4ffd45 100644 +index a0a382643a2f74b6d789f3641ef300eed202d5e9..7a2be5fe6cdecb771ce3326008085ae402a465de 100644 --- a/browser/base/content/navigator-toolbox.inc.xhtml +++ b/browser/base/content/navigator-toolbox.inc.xhtml @@ -2,7 +2,7 @@ @@ -46,7 +46,7 @@ index a0a382643a2f74b6d789f3641ef300eed202d5e9..fd60aceee18e22d40c7d86506408803e stopwatchid="FX_TAB_CLICK_MS"> + + -+ ++ +