diff --git a/src/browser/base/content/zen-assets.jar.inc.mn b/src/browser/base/content/zen-assets.jar.inc.mn index 96ac35a48..6743b140c 100644 --- a/src/browser/base/content/zen-assets.jar.inc.mn +++ b/src/browser/base/content/zen-assets.jar.inc.mn @@ -9,6 +9,7 @@ content/browser/ZenCustomizableUI.sys.mjs (../../zen/common/ZenCustomizableUI.sys.mjs) content/browser/zen-components/ZenUIMigration.mjs (../../zen/common/ZenUIMigration.mjs) content/browser/zen-components/ZenCommonUtils.mjs (../../zen/common/ZenCommonUtils.mjs) + content/browser/zen-components/ZenSessionStore.mjs (../../zen/common/ZenSessionStore.mjs) content/browser/zen-styles/zen-theme.css (../../zen/common/styles/zen-theme.css) content/browser/zen-styles/zen-buttons.css (../../zen/common/styles/zen-buttons.css) diff --git a/src/browser/base/content/zen-preloaded.inc.xhtml b/src/browser/base/content/zen-preloaded.inc.xhtml index 5cc1fb9b4..6f081c4de 100644 --- a/src/browser/base/content/zen-preloaded.inc.xhtml +++ b/src/browser/base/content/zen-preloaded.inc.xhtml @@ -9,3 +9,5 @@ + + diff --git a/src/browser/components/sessionstore/SessionStore-sys-mjs.patch b/src/browser/components/sessionstore/SessionStore-sys-mjs.patch index 8b3c8958b..0ca80237c 100644 --- a/src/browser/components/sessionstore/SessionStore-sys-mjs.patch +++ b/src/browser/components/sessionstore/SessionStore-sys-mjs.patch @@ -1,5 +1,5 @@ diff --git a/browser/components/sessionstore/SessionStore.sys.mjs b/browser/components/sessionstore/SessionStore.sys.mjs -index 8c6047e1ada5a22e57e1e665965237c9e22641d7..ccd2779d66eda9d034ca51cc3200d81447514e2c 100644 +index 8c6047e1ada5a22e57e1e665965237c9e22641d7..8d0585e738a5a758ebbddfa0787c71d634dadd4d 100644 --- a/browser/components/sessionstore/SessionStore.sys.mjs +++ b/browser/components/sessionstore/SessionStore.sys.mjs @@ -2088,7 +2088,6 @@ var SessionStoreInternal = { @@ -31,17 +31,19 @@ index 8c6047e1ada5a22e57e1e665965237c9e22641d7..ccd2779d66eda9d034ca51cc3200d814 return; } -@@ -3925,6 +3922,9 @@ var SessionStoreInternal = { +@@ -3925,6 +3922,11 @@ var SessionStoreInternal = { Math.min(tabState.index, tabState.entries.length) ); tabState.pinned = false; + tabState.zenEssential = false; + tabState.zenPinnedId = null; ++ tabState.zenIsGlance = false; ++ tabState.zenGlanceId = null; + tabState.zenHasStaticLabel = false; if (inBackground === false) { aWindow.gBrowser.selectedTab = newTab; -@@ -5239,7 +5239,7 @@ var SessionStoreInternal = { +@@ -5239,7 +5241,7 @@ var SessionStoreInternal = { } let workspaceID = aWindow.getWorkspaceID(); @@ -50,7 +52,7 @@ index 8c6047e1ada5a22e57e1e665965237c9e22641d7..ccd2779d66eda9d034ca51cc3200d814 winData.workspaceID = workspaceID; } }, -@@ -5430,14 +5430,15 @@ var SessionStoreInternal = { +@@ -5430,14 +5432,15 @@ var SessionStoreInternal = { } let tabbrowser = aWindow.gBrowser; @@ -68,7 +70,7 @@ index 8c6047e1ada5a22e57e1e665965237c9e22641d7..ccd2779d66eda9d034ca51cc3200d814 continue; } let tabData = lazy.TabState.collect(tab, TAB_CUSTOM_VALUES.get(tab)); -@@ -5456,8 +5457,8 @@ var SessionStoreInternal = { +@@ -5456,8 +5459,8 @@ var SessionStoreInternal = { // We don't store the Firefox View tab in Session Store, so if it was the last selected "tab" when // a window is closed, point to the first item in the tab strip instead (it will never be the Firefox View tab, // since it's only inserted into the tab strip after it's selected). @@ -79,7 +81,7 @@ index 8c6047e1ada5a22e57e1e665965237c9e22641d7..ccd2779d66eda9d034ca51cc3200d814 winData.title = tabbrowser.tabs[0].label; } winData.selected = selectedIndex; -@@ -5569,8 +5570,8 @@ var SessionStoreInternal = { +@@ -5569,8 +5572,8 @@ var SessionStoreInternal = { // selectTab represents. let selectTab = 0; if (overwriteTabs) { @@ -90,7 +92,7 @@ index 8c6047e1ada5a22e57e1e665965237c9e22641d7..ccd2779d66eda9d034ca51cc3200d814 selectTab = Math.min(selectTab, winData.tabs.length); } -@@ -5613,6 +5614,7 @@ var SessionStoreInternal = { +@@ -5613,6 +5616,7 @@ var SessionStoreInternal = { winData.tabs, winData.groups ?? [] ); @@ -98,12 +100,13 @@ index 8c6047e1ada5a22e57e1e665965237c9e22641d7..ccd2779d66eda9d034ca51cc3200d814 this._log.debug( `restoreWindow, createTabsForSessionRestore returned ${tabs.length} tabs` ); -@@ -6162,8 +6164,23 @@ var SessionStoreInternal = { +@@ -6162,6 +6166,22 @@ var SessionStoreInternal = { // Most of tabData has been restored, now continue with restoring // attributes that may trigger external events. + if (tabData.zenEssential) { + tab.setAttribute("zen-essential", "true"); ++ tabData.pinned = true; // Essential tabs are always pinned. + } + if (tabData.zenIsEmpty) { + tab.setAttribute("zen-empty-tab", "true"); @@ -118,8 +121,5 @@ index 8c6047e1ada5a22e57e1e665965237c9e22641d7..ccd2779d66eda9d034ca51cc3200d814 + tab.setAttribute("zenDefaultUserContextId", true); + } -- if (tabData.pinned) { -+ if (tabData.pinned || tabData.zenEssential) { + if (tabData.pinned) { tabbrowser.pinTab(tab); - } else { - tabbrowser.unpinTab(tab); diff --git a/src/browser/components/sessionstore/TabState-sys-mjs.patch b/src/browser/components/sessionstore/TabState-sys-mjs.patch index c3c77e19f..bab8ebf1e 100644 --- a/src/browser/components/sessionstore/TabState-sys-mjs.patch +++ b/src/browser/components/sessionstore/TabState-sys-mjs.patch @@ -1,8 +1,8 @@ diff --git a/browser/components/sessionstore/TabState.sys.mjs b/browser/components/sessionstore/TabState.sys.mjs -index 8f7ed557e6aa61e7e16ed4a8d785ad5fe651b3d8..254849e13f7566029dc780c45e376e0f0d427cb5 100644 +index 8f7ed557e6aa61e7e16ed4a8d785ad5fe651b3d8..76f4cf5aef30cb580ef0295fe6928b5a6a362f4b 100644 --- a/browser/components/sessionstore/TabState.sys.mjs +++ b/browser/components/sessionstore/TabState.sys.mjs -@@ -84,6 +84,16 @@ class _TabState { +@@ -84,6 +84,18 @@ class _TabState { tabData.groupId = tab.group.id; } @@ -15,6 +15,8 @@ index 8f7ed557e6aa61e7e16ed4a8d785ad5fe651b3d8..254849e13f7566029dc780c45e376e0f + tabData.zenPinnedIcon = tab.getAttribute("zen-pinned-icon"); + tabData.zenIsEmpty = tab.hasAttribute("zen-empty-tab"); + tabData.zenHasStaticLabel = tab.hasAttribute("zen-has-static-label"); ++ tabData.zenGlanceId = tab.getAttribute("glance-id"); ++ tabData.zenIsGlance = tab.hasAttribute("zen-glance-tab"); + tabData.searchMode = tab.ownerGlobal.gURLBar.getSearchMode(browser, true); diff --git a/src/browser/components/tabbrowser/content/tabbrowser-js.patch b/src/browser/components/tabbrowser/content/tabbrowser-js.patch index e028d0f09..e60a39f7f 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 d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b032cf200f1 100644 +index d5aa64842a35c6697263c63fd3a0571b64b01344..14f5bc046f2e54109bd3fd0402a8f8b598a513c2 100644 --- a/browser/components/tabbrowser/content/tabbrowser.js +++ b/browser/components/tabbrowser/content/tabbrowser.js @@ -413,11 +413,41 @@ @@ -292,37 +292,17 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 let url = "about:blank"; if (tabData.entries?.length) { -@@ -3598,7 +3675,29 @@ +@@ -3598,7 +3675,8 @@ skipLoad: true, preferredRemoteType, }); +- + tab._originalUrl = url; - -+ if (tabData.zenWorkspace) { -+ tab.setAttribute("zen-workspace-id", tabData.zenWorkspace); -+ } -+ if (tabData.zenPinnedId) { -+ tab.setAttribute("zen-pin-id", tabData.zenPinnedId); -+ } -+ if (tabData.zenIsEmpty) { -+ tab.setAttribute("zen-empty-tab", "true"); -+ } -+ if (tabData.zenHasStaticLabel) { -+ tab.setAttribute("zen-has-static-label", "true"); -+ } -+ if (tabData.zenEssential) { -+ tab.setAttribute("zen-essential", "true"); -+ } -+ if (tabData.zenDefaultUserContextId) { -+ tab.setAttribute("zenDefaultUserContextId", "true"); -+ } -+ if (tabData.zenPinnedEntry) { -+ tab.setAttribute("zen-pinned-entry", tabData.zenPinnedEntry); -+ } ++ gZenSessionStore.restoreInitialTabData(tab, tabData); if (select) { tabToSelect = tab; } -@@ -3622,7 +3721,8 @@ +@@ -3622,7 +3700,8 @@ // needs calling: shouldUpdateForPinnedTabs = true; } @@ -332,7 +312,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 let { groupId } = tabData; const tabGroup = tabGroupWorkingData.get(groupId); // if a tab refers to a tab group we don't know, skip any group -@@ -3636,7 +3736,10 @@ +@@ -3636,7 +3715,10 @@ tabGroup.stateData.id, tabGroup.stateData.color, tabGroup.stateData.collapsed, @@ -344,7 +324,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 ); tabsFragment.appendChild(tabGroup.node); } -@@ -3684,8 +3787,16 @@ +@@ -3684,8 +3766,16 @@ // to remove the old selected tab. if (tabToSelect) { let leftoverTab = this.selectedTab; @@ -363,7 +343,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 } if (tabs.length > 1 || !tabs[0].selected) { -@@ -3881,7 +3992,7 @@ +@@ -3881,7 +3971,7 @@ // Ensure we have an index if one was not provided. if (typeof elementIndex != "number" && typeof tabIndex != "number") { // Move the new tab after another tab if needed, to the end otherwise. @@ -372,7 +352,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 if ( !bulkOrderedOpen && ((openerTab && -@@ -3904,7 +4015,7 @@ +@@ -3904,7 +3994,7 @@ ) { elementIndex = Infinity; } else if (previousTab.visible) { @@ -381,7 +361,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 } else if (previousTab == FirefoxViewHandler.tab) { elementIndex = 0; } -@@ -3932,10 +4043,10 @@ +@@ -3932,14 +4022,14 @@ } // Ensure index is within bounds. if (tab.pinned) { @@ -395,7 +375,12 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 index = Math.min(index, allItems.length); } /** @type {MozTabbrowserTab|undefined} */ -@@ -3947,7 +4058,7 @@ +- let itemAfter = allItems.at(index); ++ let itemAfter = gZenGlanceManager.getTabOrGlanceParent(allItems.at(index)); + + // Prevent a flash of unstyled content by setting up the tab content + // and inherited attributes before appending it (see Bug 1592054): +@@ -3947,7 +4037,7 @@ this.tabContainer._invalidateCachedTabs(); @@ -404,7 +389,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 if (this.isTab(itemAfter) && itemAfter.group == tabGroup) { // Place at the front of, or between tabs in, the same tab group this.tabContainer.insertBefore(tab, itemAfter); -@@ -4268,6 +4379,9 @@ +@@ -4268,6 +4358,9 @@ return; } @@ -414,7 +399,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 this.removeTabs(selectedTabs, { telemetrySource }); } -@@ -4520,6 +4634,7 @@ +@@ -4520,6 +4613,7 @@ telemetrySource, } = {} ) { @@ -422,7 +407,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 // When 'closeWindowWithLastTab' pref is enabled, closing all tabs // can be considered equivalent to closing the window. if ( -@@ -4604,6 +4719,7 @@ +@@ -4604,6 +4698,7 @@ if (lastToClose) { this.removeTab(lastToClose, aParams); } @@ -430,7 +415,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 } catch (e) { console.error(e); } -@@ -4641,6 +4757,12 @@ +@@ -4641,6 +4736,12 @@ aTab._closeTimeNoAnimTimerId = Glean.browserTabclose.timeNoAnim.start(); } @@ -443,7 +428,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 // Handle requests for synchronously removing an already // asynchronously closing tab. if (!animate && aTab.closing) { -@@ -4655,7 +4777,9 @@ +@@ -4655,7 +4756,9 @@ // frame created for it (for example, by updating the visually selected // state). let tabWidth = window.windowUtils.getBoundsWithoutFlushing(aTab).width; @@ -454,7 +439,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 if ( !this._beginRemoveTab(aTab, { closeWindowFastpath: true, -@@ -4821,7 +4945,7 @@ +@@ -4821,7 +4924,7 @@ closeWindowWithLastTab != null ? closeWindowWithLastTab : !window.toolbar.visible || @@ -463,7 +448,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 if (closeWindow) { // We've already called beforeunload on all the relevant tabs if we get here, -@@ -4845,6 +4969,7 @@ +@@ -4845,6 +4948,7 @@ newTab = true; } @@ -471,7 +456,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 aTab._endRemoveArgs = [closeWindow, newTab]; // swapBrowsersAndCloseOther will take care of closing the window without animation. -@@ -4885,9 +5010,7 @@ +@@ -4885,9 +4989,7 @@ aTab._mouseleave(); if (newTab) { @@ -482,7 +467,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 } else { TabBarVisibility.update(); } -@@ -5016,6 +5139,8 @@ +@@ -5016,6 +5118,8 @@ this.tabs[i]._tPos = i; } @@ -491,7 +476,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 if (!this._windowIsClosing) { if (wasPinned) { this.tabContainer._positionPinnedTabs(); -@@ -5230,6 +5355,7 @@ +@@ -5230,6 +5334,7 @@ } let excludeTabs = new Set(aExcludeTabs); @@ -499,7 +484,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 // If this tab has a successor, it should be selectable, since // hiding or closing a tab removes that tab as a successor. -@@ -5242,13 +5368,13 @@ +@@ -5242,13 +5347,13 @@ !excludeTabs.has(aTab.owner) && Services.prefs.getBoolPref("browser.tabs.selectOwnerOnClose") ) { @@ -515,7 +500,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 ); let tab = this.tabContainer.findNextTab(aTab, { -@@ -5264,7 +5390,7 @@ +@@ -5264,7 +5369,7 @@ } if (tab) { @@ -524,7 +509,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 } // If no qualifying visible tab was found, see if there is a tab in -@@ -5285,7 +5411,7 @@ +@@ -5285,7 +5390,7 @@ }); } @@ -533,7 +518,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 } _blurTab(aTab) { -@@ -5686,10 +5812,10 @@ +@@ -5686,10 +5791,10 @@ SessionStore.deleteCustomTabValue(aTab, "hiddenBy"); } @@ -546,7 +531,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 aTab.selected || aTab.closing || // Tabs that are sharing the screen, microphone or camera cannot be hidden. -@@ -5986,7 +6112,7 @@ +@@ -5986,7 +6091,7 @@ // Don't allow mixing pinned and unpinned tabs. if (this.isTab(element) && element.pinned) { @@ -555,7 +540,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 } else { tabIndex = Math.max(tabIndex, this.pinnedTabCount); } -@@ -6012,10 +6138,16 @@ +@@ -6012,10 +6117,16 @@ this.#handleTabMove( element, () => { @@ -574,7 +559,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 if (neighbor && this.isTab(element) && tabIndex > element._tPos) { neighbor.after(element); } else { -@@ -6084,17 +6216,26 @@ +@@ -6084,17 +6195,29 @@ targetElement = targetElement.group; } } @@ -583,8 +568,12 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 + element = element.group; + } // Don't allow mixing pinned and unpinned tabs. - if (element.pinned && !targetElement?.pinned) { +- if (element.pinned && !targetElement?.pinned) { - targetElement = this.tabs[this.pinnedTabCount - 1]; ++ if (element.hasAttribute('zen-essential') && !targetElement?.hasAttribute('zen-essential')) { ++ targetElement = this.tabs.filter(tab => !tab.hasAttribute('zen-glance-tab'))[this._numZenEssentials - 1]; ++ moveBefore = false; ++ } else if (element.pinned && !targetElement?.pinned) { + targetElement = this.tabs.filter(tab => !tab.hasAttribute('zen-glance-tab'))[this.pinnedTabCount - 1]; moveBefore = false; } else if (!element.pinned && targetElement && targetElement.pinned) { @@ -604,7 +593,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 if (element.pinned && this.tabContainer.verticalMode) { return this.tabContainer.verticalPinnedTabsContainer; } -@@ -6154,7 +6295,7 @@ +@@ -6154,7 +6277,7 @@ if (!this.isTab(aTab)) { throw new Error("Can only move a tab into a tab group"); } @@ -613,7 +602,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 return; } if (aTab.group && aTab.group.id === aGroup.id) { -@@ -6248,6 +6389,10 @@ +@@ -6248,6 +6371,10 @@ moveActionCallback(); @@ -624,7 +613,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 // Clear tabs cache after moving nodes because the order of tabs may have // changed. this.tabContainer._invalidateCachedTabs(); -@@ -7145,7 +7290,7 @@ +@@ -7145,7 +7272,7 @@ // preventDefault(). It will still raise the window if appropriate. break; } @@ -633,7 +622,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 window.focus(); aEvent.preventDefault(); break; -@@ -8044,6 +8189,7 @@ +@@ -8044,6 +8171,7 @@ aWebProgress.isTopLevel ) { this.mTab.setAttribute("busy", "true"); @@ -641,7 +630,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 gBrowser._tabAttrModified(this.mTab, ["busy"]); this.mTab._notselectedsinceload = !this.mTab.selected; } -@@ -9009,7 +9155,7 @@ var TabContextMenu = { +@@ -9009,7 +9137,7 @@ var TabContextMenu = { ); contextUnpinSelectedTabs.hidden = !this.contextTab.pinned || !this.multiselected; @@ -650,7 +639,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03 // Move Tab items let contextMoveTabOptions = document.getElementById( "context_moveTabOptions" -@@ -9278,6 +9424,7 @@ var TabContextMenu = { +@@ -9278,6 +9406,7 @@ var TabContextMenu = { telemetrySource: gBrowser.TabMetrics.METRIC_SOURCE.TAB_STRIP, }); } else { diff --git a/src/browser/components/tabbrowser/content/tabgroup-js.patch b/src/browser/components/tabbrowser/content/tabgroup-js.patch new file mode 100644 index 000000000..2e392c86b --- /dev/null +++ b/src/browser/components/tabbrowser/content/tabgroup-js.patch @@ -0,0 +1,13 @@ +diff --git a/browser/components/tabbrowser/content/tabgroup.js b/browser/components/tabbrowser/content/tabgroup.js +index 6dc774ea335b0c5dba7dcf76cdb23728faae1343..b0b9ef236c2e8517db4bcf3270596456bbefe11d 100644 +--- a/browser/components/tabbrowser/content/tabgroup.js ++++ b/browser/components/tabbrowser/content/tabgroup.js +@@ -301,7 +301,7 @@ + */ + addTabs(tabs, metricsContext) { + for (let tab of tabs) { +- if (tab.pinned) { ++ if (tab.pinned !== this.pinned) { + tab.ownerGlobal.gBrowser.unpinTab(tab); + } + let tabToMove = diff --git a/src/browser/components/tabbrowser/content/tabs-js.patch b/src/browser/components/tabbrowser/content/tabs-js.patch index 6b263722d..58608e791 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 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea9596403cef 100644 +index 84d633471c89230b981d8a07babef4e0c76c0338..7cef57d99eca61f49968a128378d71c44f52556e 100644 --- a/browser/components/tabbrowser/content/tabs.js +++ b/browser/components/tabbrowser/content/tabs.js @@ -83,7 +83,7 @@ @@ -46,6 +46,15 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 expandGroupOnDrop = true; } } +@@ -868,7 +869,7 @@ + ? event.screenY - window.screenY - tabOffset + : event.screenY - window.screenY, + scrollPos: +- this.verticalMode && tab.pinned ++ this.verticalMode && tab.pinned && false + ? this.verticalPinnedTabsContainer.scrollPosition + : this.arrowScrollbox.scrollPosition, + screenX: event.screenX, @@ -921,6 +922,10 @@ } @@ -76,31 +85,32 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 if (draggedTab && dropEffect == "copy") { let duplicatedDraggedTab; let duplicatedTabs = []; -@@ -1116,10 +1133,11 @@ +@@ -1116,7 +1133,7 @@ } } else { let isPinned = draggedTab.pinned; - let numPinned = gBrowser.pinnedTabCount; + let numPinned = gBrowser._numVisiblePinTabsWithoutCollapsed; -+ let essential = draggedTab.hasAttribute("zen-essential"); let tabs = this.ariaFocusableItems.slice( -- isPinned ? 0 : numPinned, -- isPinned ? numPinned : undefined -+ isPinned ? (essential ? 0 : gBrowser._numZenEssentials) : numPinned, -+ isPinned ? (essential ? gBrowser._numZenEssentials : numPinned) : undefined - ); - let size = this.verticalMode ? "height" : "width"; - let screenAxis = this.verticalMode ? "screenY" : "screenX"; -@@ -1211,7 +1229,7 @@ - item.removeAttribute("tabdrop-samewindow"); - resolve(); - }; -- if (gReduceMotion) { -+ if (true || gReduceMotion) { - postTransitionCleanup(); - } else { - let onTransitionEnd = transitionendEvent => { -@@ -1337,6 +1355,7 @@ + isPinned ? 0 : numPinned, + isPinned ? numPinned : undefined +@@ -1135,8 +1152,14 @@ + (lastMovingTabScreen + tabSize); + + if (this.verticalMode) { ++ if (oldTranslateY > 0 && translateOffsetY > tabHeight / 2) { ++ newTranslateY += tabHeight; ++ } ++ if (oldTranslateY < 0 && -translateOffsetY > tabHeight / 2) { ++ newTranslateY -= tabHeight; ++ } + newTranslateY = Math.min( +- Math.max(oldTranslateY, firstBound), ++ Math.max(newTranslateY, firstBound), + lastBound + ); + } else { +@@ -1337,6 +1360,7 @@ let nextItem = this.ariaFocusableItems[newIndex]; let tabGroup = isTab(nextItem) && nextItem.group; @@ -108,7 +118,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 gBrowser.loadTabs(urls, { inBackground, replace, -@@ -1369,6 +1388,17 @@ +@@ -1369,6 +1393,17 @@ this.finishMoveTogetherSelectedTabs(draggedTab); this.finishAnimateTabMove(); @@ -126,7 +136,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 this.#expandGroupOnDrop(draggedTab); if ( -@@ -1597,7 +1627,7 @@ +@@ -1597,7 +1632,7 @@ } get newTabButton() { @@ -135,7 +145,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 } get verticalMode() { -@@ -1621,29 +1651,54 @@ +@@ -1621,29 +1656,54 @@ if (this.#allTabs) { return this.#allTabs; } @@ -198,7 +208,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 } /** -@@ -1698,23 +1753,18 @@ +@@ -1698,23 +1758,18 @@ } let elementIndex = 0; @@ -226,7 +236,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 let visibleTabsInGroup = child.tabs.filter(tab => tab.visible); visibleTabsInGroup.forEach(tab => { tab.elementIndex = elementIndex++; -@@ -1724,10 +1774,7 @@ +@@ -1724,10 +1779,7 @@ } } @@ -238,7 +248,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 return this.#focusableItems; } -@@ -1735,6 +1782,7 @@ +@@ -1735,6 +1787,7 @@ _invalidateCachedTabs() { this.#allTabs = null; this._invalidateCachedVisibleTabs(); @@ -246,7 +256,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 } _invalidateCachedVisibleTabs() { -@@ -1749,8 +1797,8 @@ +@@ -1749,8 +1802,8 @@ #isContainerVerticalPinnedGrid(tab) { return ( this.verticalMode && @@ -257,7 +267,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 !this.expandOnHover ); } -@@ -1766,7 +1814,7 @@ +@@ -1766,7 +1819,7 @@ if (node == null) { // We have a container for non-tab elements at the end of the scrollbox. @@ -266,7 +276,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 } node.before(tab); -@@ -1861,7 +1909,7 @@ +@@ -1861,7 +1914,7 @@ // There are separate "new tab" buttons for horizontal tabs toolbar, vertical tabs and // for when the tab strip is overflowed (which is shared by vertical and horizontal tabs); // Attach the long click popup to all of them. @@ -275,7 +285,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 const newTab2 = this.newTabButton; const newTabVertical = document.getElementById( "vertical-tabs-newtab-button" -@@ -1956,10 +2004,12 @@ +@@ -1956,10 +2009,12 @@ _handleTabSelect(aInstant) { let selectedTab = this.selectedItem; @@ -288,7 +298,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 selectedTab._notselectedsinceload = false; } -@@ -2132,6 +2182,7 @@ +@@ -2132,6 +2187,7 @@ } _positionPinnedTabs() { @@ -296,7 +306,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 let tabs = this.visibleTabs; let numPinned = gBrowser.pinnedTabCount; let absPositionHorizontalTabs = -@@ -2206,7 +2257,7 @@ +@@ -2206,7 +2262,7 @@ return; } @@ -305,16 +315,25 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 let directionX = screenX > dragData.animLastScreenX; let directionY = screenY > dragData.animLastScreenY; -@@ -2214,7 +2265,7 @@ - dragData.animLastScreenX = screenX; +@@ -2215,6 +2271,8 @@ let { width: tabWidth, height: tabHeight } = -- draggedTab.getBoundingClientRect(); -+ (draggedTab.group?.hasAttribute("split-view-group") ? draggedTab.group : draggedTab).getBoundingClientRect(); + draggedTab.getBoundingClientRect(); ++ tabWidth += 4; // Add 4px to account for the gap ++ tabHeight += 4; let shiftSizeX = tabWidth * movingTabs.length; let shiftSizeY = tabHeight; dragData.tabWidth = tabWidth; -@@ -2389,12 +2440,16 @@ +@@ -2244,7 +2302,7 @@ + let translateX = screenX - dragData.screenX; + let translateY = screenY - dragData.screenY; + translateY += +- this.verticalPinnedTabsContainer.scrollPosition - dragData.scrollPos; ++ dragData.scrollPos; + let firstBoundX = firstTabInRow.screenX - firstMovingTabScreenX; + let firstBoundY = firstTabInRow.screenY - firstMovingTabScreenY; + let lastBoundX = +@@ -2389,12 +2447,16 @@ this.#clearDragOverCreateGroupTimer(); @@ -335,7 +354,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 if (this.#rtlMode) { tabs.reverse(); -@@ -2408,7 +2463,7 @@ +@@ -2408,7 +2470,7 @@ let size = this.verticalMode ? "height" : "width"; let translateAxis = this.verticalMode ? "translateY" : "translateX"; let scrollDirection = this.verticalMode ? "scrollTop" : "scrollLeft"; @@ -344,7 +363,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 let translateX = event.screenX - dragData.screenX; let translateY = event.screenY - dragData.screenY; -@@ -2422,12 +2477,21 @@ +@@ -2422,12 +2484,21 @@ let lastTab = tabs.at(-1); let lastMovingTab = movingTabs.at(-1); let firstMovingTab = movingTabs[0]; @@ -367,7 +386,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 translate += this.arrowScrollbox.scrollbox[scrollDirection] - dragData.scrollPos; } else if (isPinned && this.verticalMode) { -@@ -2446,6 +2510,9 @@ +@@ -2446,6 +2517,9 @@ // Shift the `.tab-group-label-container` to shift the label element. item = item.parentElement; } @@ -377,7 +396,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 item.style.transform = `${translateAxis}(${translate}px)`; } -@@ -2583,6 +2650,9 @@ +@@ -2583,6 +2657,9 @@ break; } let element = tabs[mid]; @@ -387,7 +406,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 let elementForSize = isTabGroupLabel(element) ? element.parentElement : element; -@@ -2605,6 +2675,10 @@ +@@ -2605,6 +2682,10 @@ if (!dropElement) { dropElement = this.ariaFocusableItems[oldDropElementIndex]; } @@ -398,7 +417,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 let newDropElementIndex = dropElement ? dropElement.elementIndex : oldDropElementIndex; -@@ -2613,7 +2687,7 @@ +@@ -2613,7 +2694,7 @@ let shouldCreateGroupOnDrop; let dropBefore; if (dropElement) { @@ -407,7 +426,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 ? dropElement.parentElement : dropElement; -@@ -2675,12 +2749,12 @@ +@@ -2675,12 +2756,12 @@ } } @@ -422,7 +441,16 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 dropElement != draggedTab && isTab(dropElement) && !dropElement?.group && -@@ -2750,7 +2824,7 @@ +@@ -2720,7 +2801,7 @@ + // Dropping right before the tab group. + dropElement = dropElementGroup; + colorCode = undefined; +- } else if (dropElementGroup.collapsed) { ++ } else if (dropElement?.group?.hasAttribute("split-view-group")) { + // Dropping right after the collapsed tab group. + dropElement = dropElementGroup; + colorCode = undefined; +@@ -2750,7 +2831,7 @@ // Shift background tabs to leave a gap where the dragged tab // would currently be dropped. for (let item of tabs) { @@ -431,7 +459,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 continue; } -@@ -2759,6 +2833,9 @@ +@@ -2759,6 +2840,9 @@ if (isTabGroupLabel(item)) { // Shift the `.tab-group-label-container` to shift the label element. item = item.parentElement; @@ -441,7 +469,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 } item.style.transform = transform; } -@@ -2811,8 +2888,9 @@ +@@ -2811,8 +2895,9 @@ ); } @@ -453,7 +481,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 return; } -@@ -2824,6 +2902,12 @@ +@@ -2824,6 +2909,12 @@ item = item.parentElement; } item.style.transform = ""; @@ -466,7 +494,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 item.removeAttribute("dragover-createGroup"); } this.removeAttribute("movingtab-createGroup"); -@@ -2870,7 +2954,7 @@ +@@ -2870,7 +2961,7 @@ let postTransitionCleanup = () => { movingTab._moveTogetherSelectedTabsData.animate = false; }; @@ -475,7 +503,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 postTransitionCleanup(); } else { let onTransitionEnd = transitionendEvent => { -@@ -3043,7 +3127,7 @@ +@@ -3043,7 +3134,7 @@ } _notifyBackgroundTab(aTab) { @@ -484,7 +512,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95 return; } -@@ -3169,6 +3253,9 @@ +@@ -3169,6 +3260,9 @@ return null; } } diff --git a/src/toolkit/themes/shared/menu-css.patch b/src/toolkit/themes/shared/menu-css.patch index f647f2d02..b94bae3a3 100644 --- a/src/toolkit/themes/shared/menu-css.patch +++ b/src/toolkit/themes/shared/menu-css.patch @@ -1,13 +1,12 @@ diff --git a/toolkit/themes/shared/menu.css b/toolkit/themes/shared/menu.css -index ecf66f30b2dd18765af467913bb0bc66a8d36a41..6b58db0c1590b0151a3e169b75d4d2ee19db912c 100644 +index ecf66f30b2dd18765af467913bb0bc66a8d36a41..8ecb03f8f09100dc76e8e4dabd13c366717268b4 100644 --- a/toolkit/themes/shared/menu.css +++ b/toolkit/themes/shared/menu.css -@@ -345,7 +345,7 @@ menuitem[highlightable] > .menu-text { +@@ -345,7 +345,6 @@ menuitem[highlightable] > .menu-text { /* On macOS and Windows, empty icons shouldn't take up any space */ menuitem:not(.menuitem-iconic, [image]) > &, menu:not(.menu-iconic) > & { - display: none; -+ } } } diff --git a/src/zen/common/ZenSessionStore.mjs b/src/zen/common/ZenSessionStore.mjs new file mode 100644 index 000000000..b43e83f14 --- /dev/null +++ b/src/zen/common/ZenSessionStore.mjs @@ -0,0 +1,99 @@ +{ + class ZenSessionStore extends ZenPreloadedFeature { + init() { + this.#waitAndCleanup(); + } + + #glanceTabs = {}; + promiseInitialized = new Promise((resolve) => { + this._resolveInitialized = resolve; + }); + + restoreInitialTabData(tab, tabData) { + if (tabData.zenWorkspace) { + tab.setAttribute('zen-workspace-id', tabData.zenWorkspace); + } + if (tabData.zenPinnedId) { + tab.setAttribute('zen-pin-id', tabData.zenPinnedId); + } + if (tabData.zenIsEmpty) { + tab.setAttribute('zen-empty-tab', 'true'); + } + if (tabData.zenHasStaticLabel) { + tab.setAttribute('zen-has-static-label', 'true'); + } + if (tabData.zenEssential) { + tab.setAttribute('zen-essential', 'true'); + } + if (tabData.zenDefaultUserContextId) { + tab.setAttribute('zenDefaultUserContextId', 'true'); + } + if (tabData.zenPinnedEntry) { + tab.setAttribute('zen-pinned-entry', tabData.zenPinnedEntry); + } + if (tabData.zenGlanceId) { + // We just found the background used for glance. Find + // the current + if (tabData.zenIsGlance) { + if (this.#glanceTabs[tabData.zenGlanceId]) { + this.#glanceTabs[tabData.zenGlanceId].tab = tab; + } else { + this.#glanceTabs[tabData.zenGlanceId] = { + tab: tab, + background: null, + }; + } + } else { + if (this.#glanceTabs[tabData.zenGlanceId]) { + this.#glanceTabs[tabData.zenGlanceId].background = tab; + } else { + this.#glanceTabs[tabData.zenGlanceId] = { + tab: null, + background: tab, + }; + } + } + } + } + + async #resolveGlanceTabs() { + for (const [id, data] of Object.entries(this.#glanceTabs)) { + const { tab, background } = data; + // TODO(Restore glance tab): Finish this implementation + continue; + + if (!tab || !background) { + tab?.removeAttribute('glance-id'); + background?.removeAttribute('glance-id'); + continue; + } + console.log(tab, background); + const browserRect = gBrowser.tabbox.getBoundingClientRect(); + await gZenGlanceManager.openGlance( + { + url: undefined, + x: browserRect.width / 2, + y: browserRect.height / 2, + width: 0, + height: 0, + }, + tab, + background + ); + } + } + + async #waitAndCleanup() { + await SessionStore.promiseInitialized; + await this.#resolveGlanceTabs(); + this.#cleanup(); + } + + #cleanup() { + this._resolveInitialized(); + delete window.gZenSessionStore; + } + } + + window.gZenSessionStore = new ZenSessionStore(); +} diff --git a/src/zen/common/ZenUIManager.mjs b/src/zen/common/ZenUIManager.mjs index 1e0a998b1..d3484501e 100644 --- a/src/zen/common/ZenUIManager.mjs +++ b/src/zen/common/ZenUIManager.mjs @@ -989,43 +989,54 @@ var gZenVerticalTabsManager = { async renameTabKeydown(event) { event.stopPropagation(); if (event.key === 'Enter') { - let label = this._tabEdited.querySelector('.tab-label-container-editing'); - let input = this._tabEdited.querySelector('#tab-label-input'); + const isTab = !!event.target.closest('.tabbrowser-tab'); + let label = isTab + ? this._tabEdited.querySelector('.tab-label-container-editing') + : this._tabEdited; + let input = document.getElementById('tab-label-input'); let newName = input.value.trim(); - // Check if name is blank, reset if so - // Always remove, so we can always rename and if it's empty, - // it will reset to the original name anyway - this._tabEdited.removeAttribute('zen-has-static-label'); - if (newName) { - gBrowser._setTabLabel(this._tabEdited, newName); - this._tabEdited.setAttribute('zen-has-static-label', 'true'); - gZenUIManager.showToast('zen-tabs-renamed'); + document.documentElement.removeAttribute('zen-renaming-tab'); + input.remove(); + if (!isTab) { + await this._tabEdited.onRenameFinished(newName); } else { - gBrowser.setTabTitle(this._tabEdited); - } - if (this._tabEdited.getAttribute('zen-pin-id')) { - // Update pin title in storage - await gZenPinnedTabManager.updatePinTitle( + // Check if name is blank, reset if so + // Always remove, so we can always rename and if it's empty, + // it will reset to the original name anyway + this._tabEdited.removeAttribute('zen-has-static-label'); + if (newName) { + gBrowser._setTabLabel(this._tabEdited, newName); + this._tabEdited.setAttribute('zen-has-static-label', 'true'); + gZenUIManager.showToast('zen-tabs-renamed'); + } else { + gBrowser.setTabTitle(this._tabEdited); + } + if (this._tabEdited.getAttribute('zen-pin-id')) { + // Update pin title in storage + await gZenPinnedTabManager.updatePinTitle( + this._tabEdited, + this._tabEdited.label, + !!newName + ); + } + + // Maybe add some confetti here?!? + gZenUIManager.motion.animate( this._tabEdited, - this._tabEdited.label, - !!newName + { + scale: [1, 0.98, 1], + }, + { + duration: 0.25, + } ); } - document.documentElement.removeAttribute('zen-renaming-tab'); - // Maybe add some confetti here?!? - gZenUIManager.motion.animate( - this._tabEdited, - { - scale: [1, 0.98, 1], - }, - { - duration: 0.25, - } - ); - - this._tabEdited.querySelector('.tab-editor-container').remove(); + const editorContainer = this._tabEdited.querySelector('.tab-editor-container'); + if (editorContainer) { + editorContainer.remove(); + } label.classList.remove('tab-label-container-editing'); this._tabEdited = null; @@ -1035,34 +1046,45 @@ var gZenVerticalTabsManager = { }, renameTabStart(event) { + const isTab = !!event.target.closest('.tabbrowser-tab'); if ( this._tabEdited || - !Services.prefs.getBoolPref('zen.tabs.rename-tabs') || - Services.prefs.getBoolPref('browser.tabs.closeTabByDblclick') || + ((!Services.prefs.getBoolPref('zen.tabs.rename-tabs') || + Services.prefs.getBoolPref('browser.tabs.closeTabByDblclick')) && + isTab) || !gZenVerticalTabsManager._prefsSidebarExpanded ) return; - this._tabEdited = event.target.closest('.tabbrowser-tab'); + this._tabEdited = + event.target.closest('.tabbrowser-tab') || + event.target.closest('.zen-current-workspace-indicator-name') || + gZenWorkspaces.activeWorkspaceIndicator.querySelector( + '.zen-current-workspace-indicator-name' + ); if ( !this._tabEdited || - !this._tabEdited.pinned || - this._tabEdited.hasAttribute('zen-essential') + ((!this._tabEdited.pinned || this._tabEdited.hasAttribute('zen-essential')) && isTab) ) { this._tabEdited = null; return; } + event.stopPropagation(); document.documentElement.setAttribute('zen-renaming-tab', 'true'); - const label = this._tabEdited.querySelector('.tab-label-container'); + const label = isTab ? this._tabEdited.querySelector('.tab-label-container') : this._tabEdited; label.classList.add('tab-label-container-editing'); - const container = window.MozXULElement.parseXULToFragment(` - - `); - label.after(container); - const containerHtml = this._tabEdited.querySelector('.tab-editor-container'); + if (isTab) { + const container = window.MozXULElement.parseXULToFragment(` + + `); + label.after(container); + } + const containerHtml = isTab + ? this._tabEdited.querySelector('.tab-editor-container') + : this._tabEdited.parentNode; const input = document.createElement('input'); input.id = 'tab-label-input'; - input.value = this._tabEdited.label; + input.value = isTab ? this._tabEdited.label : this._tabEdited.textContent; input.addEventListener('keydown', this.renameTabKeydown.bind(this)); containerHtml.appendChild(input); @@ -1077,8 +1099,16 @@ var gZenVerticalTabsManager = { return; } document.documentElement.removeAttribute('zen-renaming-tab'); - this._tabEdited.querySelector('.tab-editor-container').remove(); - const label = this._tabEdited.querySelector('.tab-label-container-editing'); + const editorContainer = this._tabEdited.querySelector('.tab-editor-container'); + let input = document.getElementById('tab-label-input'); + input.remove(); + if (editorContainer) { + editorContainer.remove(); + } + const isTab = !!this._tabEdited.closest('.tabbrowser-tab'); + const label = isTab + ? this._tabEdited.querySelector('.tab-label-container-editing') + : this._tabEdited; label.classList.remove('tab-label-container-editing'); this._tabEdited = null; diff --git a/src/zen/glance/ZenGlanceManager.mjs b/src/zen/glance/ZenGlanceManager.mjs index 310bc4889..be161b3c2 100644 --- a/src/zen/glance/ZenGlanceManager.mjs +++ b/src/zen/glance/ZenGlanceManager.mjs @@ -705,8 +705,8 @@ } getTabOrGlanceParent(tab) { - if (tab?.hasAttribute('glance-id')) { - const parentTab = this.#glances.get(tab.getAttribute('glance-id')).parentTab; + if (tab?.hasAttribute('glance-id') && this.#glances) { + const parentTab = this.#glances.get(tab.getAttribute('glance-id'))?.parentTab; if (parentTab) { return parentTab; } diff --git a/src/zen/split-view/ZenViewSplitter.mjs b/src/zen/split-view/ZenViewSplitter.mjs index 086f83386..e9a8d8d5f 100644 --- a/src/zen/split-view/ZenViewSplitter.mjs +++ b/src/zen/split-view/ZenViewSplitter.mjs @@ -104,6 +104,7 @@ class ZenViewSplitter extends ZenDOMOperatedFeature { ); window.addEventListener('TabClose', this.handleTabClose.bind(this)); + window.addEventListener('TabBrowserDiscarded', this.handleTabBrowserDiscarded.bind(this)); window.addEventListener('TabSelect', this.onTabSelect.bind(this)); this.initializeContextMenu(); this.insertIntoContextMenu(); @@ -150,6 +151,17 @@ class ZenViewSplitter extends ZenDOMOperatedFeature { this.removeTabFromGroup(tab, groupIndex, true); } + /** + * @param {Event} event - The event that triggered the tab browser discard. + * @description Handles the tab browser discard event. + */ + async handleTabBrowserDiscarded(event) { + const tab = event.target; + if (tab.group?.hasAttribute('split-view-group')) { + gBrowser.explicitUnloadTabs(tab.group.tabs); + } + } + /** * @param {Event} event - The event that triggered the tab select. * @description Handles the tab select event. diff --git a/src/zen/tabs/zen-tabs/vertical-tabs.css b/src/zen/tabs/zen-tabs/vertical-tabs.css index 4af16fbac..d1c4b0017 100644 --- a/src/zen/tabs/zen-tabs/vertical-tabs.css +++ b/src/zen/tabs/zen-tabs/vertical-tabs.css @@ -356,6 +356,7 @@ margin-block: 0 !important; margin-inline: 0 !important; box-shadow: none !important; + border-radius: calc(var(--border-radius-medium) - 2px); } /* Adjust padding for content */ & .tab-content { @@ -374,6 +375,27 @@ width: 14px; height: 14px; } + + & .tab-audio-button { + display: none !important; + } + + &[soundplaying]:not([muted]) .tab-icon-stack::after { + content: ''; + position: absolute; + width: 110%; + height: 110%; + background-repeat: no-repeat; + opacity: 1; + background: url('chrome://browser/content/zen-images/note-indicator.svg') no-repeat; + top: -70%; + left: 50%; + transform: translateX(-50%); + z-index: 0; + pointer-events: none; + transition: opacity 0.8s ease; + opacity: 1; + } } /* --- Essentials Glance Tab Specifics (Floating) --- */ @@ -1239,7 +1261,7 @@ padding-bottom: var(--zen-toolbox-padding); overflow: hidden; - gap: calc(var(--zen-toolbox-padding) - 2px); + gap: 4px; transition: max-height 0.3s ease-out, grid-template-columns 0.3s ease-out; diff --git a/src/zen/workspaces/ZenWorkspaces.mjs b/src/zen/workspaces/ZenWorkspaces.mjs index 920184e2d..ed246af0d 100644 --- a/src/zen/workspaces/ZenWorkspaces.mjs +++ b/src/zen/workspaces/ZenWorkspaces.mjs @@ -42,11 +42,6 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature { this._resolveInitialized = resolve; }); - workspaceIndicatorXUL = ` - - - `; - async waitForPromises() { if (this.privateWindowOrDisabled) { return; @@ -858,6 +853,9 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature { console.error('gZenWorkspaces: Error initializing theme picker', e); } this.onWindowResize(); + if (window.gZenSessionStore) { + await gZenSessionStore.promiseInitialized; + } await this._selectStartPage(); this._fixTabPositions(); this._resolveInitialized(); @@ -915,7 +913,7 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature { ) { this.log(`Found tab to select: ${this._tabToSelect}, ${tabs.length}`); setTimeout(() => { - gBrowser.selectedTab = tabs[this._tabToSelect]; + gBrowser.selectedTab = gZenGlanceManager.getTabOrGlanceParent(tabs[this._tabToSelect]); this._removedByStartupPage = true; gBrowser.removeTab(this._tabToRemoveForEmpty, { skipSessionStore: true, @@ -2941,6 +2939,9 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature { } _initializeWorkspaceTabContextMenus() { + if (this.privateWindowOrDisabled) { + return; + } const menu = document.createXULElement('menu'); menu.setAttribute('id', 'context-zen-change-workspace-tab'); menu.setAttribute('data-l10n-id', 'context-zen-change-workspace-tab');