diff --git a/src/browser/base/content/ZenStartup.mjs b/src/browser/base/content/ZenStartup.mjs index a8880efdd..a09e51f47 100644 --- a/src/browser/base/content/ZenStartup.mjs +++ b/src/browser/base/content/ZenStartup.mjs @@ -85,7 +85,6 @@ _initSidebarScrolling() { // Disable smooth scroll const canSmoothScroll = Services.prefs.getBoolPref('zen.startup.smooth-scroll-in-tabs', false); - const workspaceIndicator = document.getElementById('zen-current-workspace-indicator'); const tabsWrapper = document.getElementById('zen-browser-tabs-wrapper'); gBrowser.tabContainer.addEventListener('wheel', (event) => { if (canSmoothScroll) return; diff --git a/src/browser/base/content/ZenUIManager.mjs b/src/browser/base/content/ZenUIManager.mjs index 46dff2042..ca3354728 100644 --- a/src/browser/base/content/ZenUIManager.mjs +++ b/src/browser/base/content/ZenUIManager.mjs @@ -413,6 +413,8 @@ 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'); 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 6d7f1a45c..bc2ef52de 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..8b7b2ae3e7764d5dd77cd344f0cf67aea54a6f47 100644 +index a0a382643a2f74b6d789f3641ef300eed202d5e9..340475da315e67b2dd4f93567547cde703a90ee8 100644 --- a/browser/base/content/navigator-toolbox.inc.xhtml +++ b/browser/base/content/navigator-toolbox.inc.xhtml @@ -2,7 +2,7 @@ @@ -40,20 +40,17 @@ index a0a382643a2f74b6d789f3641ef300eed202d5e9..8b7b2ae3e7764d5dd77cd344f0cf67ae + -+ -+ -+ -+ ++ + @@ -86,7 +83,7 @@ index a0a382643a2f74b6d789f3641ef300eed202d5e9..8b7b2ae3e7764d5dd77cd344f0cf67ae diff --git a/src/browser/base/content/zen-styles/zen-browser-ui.css b/src/browser/base/content/zen-styles/zen-browser-ui.css index 403370c63..0257ac92f 100644 --- a/src/browser/base/content/zen-styles/zen-browser-ui.css +++ b/src/browser/base/content/zen-styles/zen-browser-ui.css @@ -51,7 +51,7 @@ &[animating='true']::after { background: var(--zen-main-browser-background-old); backdrop-filter: blur(5px); - animation: zen-main-app-wrapper-animation 0.5s ease forwards; + animation: zen-main-app-wrapper-animation 0.2s ease forwards; transition: 0s; } } diff --git a/src/browser/base/content/zen-styles/zen-tabs/horizontal-tabs.css b/src/browser/base/content/zen-styles/zen-tabs/horizontal-tabs.css index e96e2fc8a..d1b2cb365 100644 --- a/src/browser/base/content/zen-styles/zen-tabs/horizontal-tabs.css +++ b/src/browser/base/content/zen-styles/zen-tabs/horizontal-tabs.css @@ -28,7 +28,7 @@ --tab-min-height: 10px !important; } - #vertical-pinned-tabs-container-separator { + .vertical-pinned-tabs-container-separator { display: none !important; } @@ -214,7 +214,7 @@ } /* Other UI Elements */ - #zen-current-workspace-indicator { + .zen-current-workspace-indicator { display: none !important; } 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 a593fedfc..b18d303c6 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 @@ -117,7 +117,7 @@ } } -#vertical-pinned-tabs-container-separator { +.vertical-pinned-tabs-container-separator { background: light-dark(rgba(1, 1, 1, 0.075), rgba(255, 255, 255, 0.1)); margin: 8px auto; border: none; @@ -126,8 +126,8 @@ 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:not(:has(tab:not([hidden]))) + &, - #tabbrowser-tabs:not(:has(#tabbrowser-arrowscrollbox tab:not([hidden]))) & { + #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]))) & { max-height: 0; margin: 0 auto; } @@ -254,18 +254,14 @@ grid-gap: 0 !important; &[overflow]::after, - #vertical-tabs-newtab-button { + #vertical-tabs-newtab-button, + #vertical-pinned-tabs-container-separator { /* notice #vertical-pinned-tabs-container-separator is an ID */ /* Hide separator they give us, eww */ display: none !important; } & .tabbrowser-tab { transition: scale 0.07s ease; - #tabbrowser-tabs &:not([zen-essential='true']) { - #tabbrowser-tabs[dont-animate-tabs] & { - opacity: 0; - } - } &:active { scale: 0.98; @@ -441,7 +437,7 @@ width: calc(100% - 10px) !important; } - & #zen-current-workspace-indicator-icon[no-icon='true'] { + & .zen-current-workspace-indicator-icon[no-icon='true'] { display: none; } @@ -572,11 +568,11 @@ #navigator-toolbox:not([zen-sidebar-expanded='true']) { max-width: var(--zen-toolbox-max-width) !important; min-width: var(--zen-toolbox-max-width) !important; - & #zen-current-workspace-indicator-name, + & .zen-current-workspace-indicator-name, & .toolbarbutton-text { display: none !important; } - & #zen-current-workspace-indicator { + & .zen-current-workspace-indicator { padding-left: 0; padding-right: 0; display: flex; @@ -893,7 +889,7 @@ align-items: center; padding-top: 0; } - + &:active, &[open] { scale: 0.98; @@ -966,7 +962,7 @@ --tab-selected-bgcolor: light-dark(rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.2)); - &:not([selected], [multiselected="true"]) .tab-background { + &:not([visuallyselected], [multiselected="true"]) .tab-background { background: var(--zen-toolbar-element-bg); border: none; } @@ -1137,3 +1133,10 @@ #zen-essentials-container .tabbrowser-tab.drag-over-after { box-shadow: -3px 0 6px -2px var(--toolbarbutton-active-background, rgba(0, 255, 0, 0.2)); } + +/* Section: tab workspaces stylings */ +.zen-workspace-tabs-section { + position: absolute; + transform: translateX(-100%); + min-width: 100%; +} diff --git a/src/browser/base/content/zen-styles/zen-theme.css b/src/browser/base/content/zen-styles/zen-theme.css index e4398c8ab..480f65c52 100644 --- a/src/browser/base/content/zen-styles/zen-theme.css +++ b/src/browser/base/content/zen-styles/zen-theme.css @@ -157,6 +157,8 @@ --zen-themed-toolbar-bg: light-dark(var(--zen-branding-bg), #161616); --zen-themed-toolbar-bg-transparent: light-dark(var(--zen-branding-bg), #161616); + --zen-workspace-indicator-height: 45px; + @media (-moz-windows-mica) or (-moz-platform: macos) { background: transparent; --zen-themed-toolbar-bg-transparency: 0; diff --git a/src/browser/base/content/zen-styles/zen-urlbar.css b/src/browser/base/content/zen-styles/zen-urlbar.css index a074fd993..fb8bf7d2a 100644 --- a/src/browser/base/content/zen-styles/zen-urlbar.css +++ b/src/browser/base/content/zen-styles/zen-urlbar.css @@ -414,7 +414,10 @@ button.popup-notification-dropmarker { --urlbar-margin-inline: 10px !important; position: absolute; - font-size: 1.5em !important; + font-size: 1.15em !important; + @media (-moz-platform: macos) { + font-size: 1.5em !important; + } top: calc(var(--zen-toolbar-height) * 2) !important; --zen-urlbar-center: calc(var(--zen-urlbar-offset, 0px) + 28vw); diff --git a/src/browser/base/content/zen-styles/zen-workspaces.css b/src/browser/base/content/zen-styles/zen-workspaces.css index a88c6a2aa..9fbe38108 100644 --- a/src/browser/base/content/zen-styles/zen-workspaces.css +++ b/src/browser/base/content/zen-styles/zen-workspaces.css @@ -446,11 +446,20 @@ } /* Mark workspaces indicator */ -#zen-current-workspace-indicator { +#zen-current-workspace-indicator-container { + margin-bottom: var(--zen-workspace-indicator-height); +} + +.zen-current-workspace-indicator { padding: 15px calc(4px + var(--tab-inline-padding)); font-weight: 600; - align-items: center; - position: relative; + position: absolute; + max-height: var(--zen-workspace-indicator-height); + min-height: var(--zen-workspace-indicator-height); + gap: 5px; + overflow: hidden; + text-overflow: ellipsis; + flex-direction: row !important; &::before { border-radius: var(--border-radius-medium); @@ -459,11 +468,11 @@ pointer-events: none; content: ''; position: absolute; - top: 6px; + top: 4px; left: 2px; z-index: -1; width: calc(100% - 4px); - height: calc(100% - 12px); + height: calc(100% - 10px); } &:hover, @@ -473,38 +482,23 @@ } } - & #zen-current-workspace-indicator-icon { - font-size: 14px; + & .zen-current-workspace-indicator-icon { + font-size: 12px; } - #zen-current-workspace-indicator-name { + .zen-current-workspace-indicator-name { font-size: 13px; opacity: 0.5; - - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; display: block; - - position: absolute; - max-width: calc(100% - var(--zen-toolbox-padding) * 4); - } - - & #zen-current-workspace-indicator-icon { - min-height: 16px; - } - - & #zen-current-workspace-indicator-icon:not([hidden]) + #zen-current-workspace-indicator-name { - padding-left: 24px; } } @media not (-moz-bool-pref: 'zen.workspaces.show-workspace-indicator') { - #zen-current-workspace-indicator { + #zen-current-workspace-indicator-container { display: none !important; } } -#zen-current-workspace-indicator[hidden='true'] { +#zen-current-workspace-indicator-container[hidden='true'] { display: none !important; } diff --git a/src/browser/base/zen-components/ZenGradientGenerator.mjs b/src/browser/base/zen-components/ZenGradientGenerator.mjs index 8080d686a..125c45da7 100644 --- a/src/browser/base/zen-components/ZenGradientGenerator.mjs +++ b/src/browser/base/zen-components/ZenGradientGenerator.mjs @@ -614,7 +614,7 @@ // Reactivate the transition after the animation appWrapper.removeAttribute('post-animating'); }, 100); - }, 500); + }, 200); }); } diff --git a/src/browser/base/zen-components/ZenPinnedTabManager.mjs b/src/browser/base/zen-components/ZenPinnedTabManager.mjs index aa2f9213d..a3487fee7 100644 --- a/src/browser/base/zen-components/ZenPinnedTabManager.mjs +++ b/src/browser/base/zen-components/ZenPinnedTabManager.mjs @@ -648,7 +648,7 @@ moveToAnotherTabContainerIfNecessary(event, draggedTab) { const pinnedTabsTarget = - event.target.closest('#vertical-pinned-tabs-container') || event.target.closest('#zen-current-workspace-indicator'); + event.target.closest('#vertical-pinned-tabs-container') || event.target.closest('.zen-current-workspace-indicator'); const essentialTabsTarget = event.target.closest('#zen-essentials-container'); const tabsTarget = event.target.closest('#tabbrowser-arrowscrollbox'); @@ -717,7 +717,7 @@ removeTabContainersDragoverClass() { this.dragIndicator.remove(); this._dragIndicator = null; - document.getElementById('zen-current-workspace-indicator').removeAttribute('open'); + ZenWorkspaces.activeWorkspaceIndicator.removeAttribute('open'); } get dragIndicator() { @@ -738,11 +738,11 @@ const essentialTabsTarget = event.target.closest('#zen-essentials-container'); const tabsTarget = event.target.closest('#tabbrowser-arrowscrollbox'); const targetTab = event.target.closest('.tabbrowser-tab'); - if (event.target.closest('#zen-current-workspace-indicator')) { + if (event.target.closest('.zen-current-workspace-indicator')) { this.removeTabContainersDragoverClass(); - event.target.setAttribute('open', true); + ZenWorkspaces.activeWorkspaceIndicator.setAttribute('open', true); } else { - document.getElementById('zen-current-workspace-indicator').removeAttribute('open'); + ZenWorkspaces.activeWorkspaceIndicator.removeAttribute('open'); } // If there's no valid target tab, nothing to do diff --git a/src/browser/base/zen-components/ZenWorkspaces.mjs b/src/browser/base/zen-components/ZenWorkspaces.mjs index 4a603d441..8198ff3a1 100644 --- a/src/browser/base/zen-components/ZenWorkspaces.mjs +++ b/src/browser/base/zen-components/ZenWorkspaces.mjs @@ -28,13 +28,18 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { this._resolvePinnedInitialized = resolve; }); + workspaceIndicatorXUL = ` + + + `; + async waitForPromises() { await Promise.all([this.promiseDBInitialized, this.promisePinnedInitialized, SessionStore.promiseAllWindowsRestored]); } async init() { if (!this.shouldHaveWorkspaces) { - document.getElementById('zen-current-workspace-indicator').setAttribute('hidden', 'true'); + document.getElementById('zen-current-workspace-indicator-container').setAttribute('hidden', 'true'); console.warn('ZenWorkspaces: !!! ZenWorkspaces is disabled in hidden windows !!!'); return; // We are in a hidden window, don't initialize ZenWorkspaces } @@ -77,6 +82,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { if (!this.workspaceEnabled) { return; } + this._pinnedTabsResizeObserver = new ResizeObserver(this.onPinnedTabsResize.bind(this)); await this.waitForPromises(); await this.initializeWorkspaces(); console.info('ZenWorkspaces: ZenWorkspaces initialized'); @@ -97,46 +103,113 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { ); } + registerPinnedResizeObserver() { + if (!this._hasInitializedTabsStrip) { + return; + } + this._pinnedTabsResizeObserver.disconnect(); + for (let element of document.getElementById('vertical-pinned-tabs-container').children) { + if (element.classList.contains('tabbrowser-tab')) { + continue; + } + this._pinnedTabsResizeObserver.observe(element); + } + } + get activeWorkspaceStrip() { + if (!this.workspaceEnabled || !this._hasInitializedTabsStrip) { + return gBrowser.tabContainer.arrowScrollbox; + } const activeWorkspace = this.activeWorkspace; - return document.querySelector(`.zen-workspace-tabs-section[zen-workspace-id="${activeWorkspace}"]`); + return document.querySelector( + `#tabbrowser-arrowscrollbox .zen-workspace-tabs-section[zen-workspace-id="${activeWorkspace}"]` + ); + } + + get activeWorkspaceIndicator() { + return document.querySelector( + `#zen-current-workspace-indicator-container .zen-workspace-tabs-section[zen-workspace-id="${this.activeWorkspace}"]` + ); } get tabboxChildren() { + return this.activeWorkspaceStrip.children; + } + + get pinnedTabsContainer() { if (!this.workspaceEnabled || !this._hasInitializedTabsStrip) { - return gBrowser.tabContainer.arrowScrollbox.children; + return document.getElementById('vertical-pinned-tabs-container'); } - return this.activeWorkspaceStrip.children + return document.querySelector( + `#vertical-pinned-tabs-container .zen-workspace-tabs-section[zen-workspace-id="${this.activeWorkspace}"]` + ); } async initializeTabsStripSections() { - const tabs = this.tabboxChildren; const perifery = document.getElementById('tabbrowser-arrowscrollbox-periphery'); + const tabs = gBrowser.tabContainer.allTabs.filter((tab) => !tab.pinned); for (const workspace of (await this._workspaces()).workspaces) { this._createWorkspaceTabsSection(workspace, tabs, perifery); } - perifery.remove(); + if (tabs.length) { + const defaultSelectedContainer = document.querySelector( + `#tabbrowser-arrowscrollbox .zen-workspace-tabs-section[zen-workspace-id="${this.activeWorkspace}"]` + ); + for (const tab of tabs) { + // before to the last child (perifery) + defaultSelectedContainer.insertBefore(tab, defaultSelectedContainer.lastChild); + } + this.tabContainer._invalidateCachedTabs(); + } + perifery.setAttribute('hidden', 'true'); this._hasInitializedTabsStrip = true; + this.registerPinnedResizeObserver(); } - async _createWorkspaceTabsSection(workspace, tabs, perifery) { - const container = gBrowser.tabContainer.arrowScrollbox; + _createWorkspaceSection(workspace) { const section = document.createXULElement('vbox'); section.className = 'zen-workspace-tabs-section'; section.setAttribute('flex', '1'); section.setAttribute('zen-workspace-id', workspace.uuid); - container.appendChild(section); - this._organizeTabsToWorkspaceSections(workspace, section, tabs); - section.appendChild(perifery.cloneNode(true)); + return section; } - _organizeTabsToWorkspaceSections(workspace, section, tabs) { + async _createWorkspaceTabsSection(workspace, tabs, perifery) { + const container = gBrowser.tabContainer.arrowScrollbox; + const section = this._createWorkspaceSection(workspace); + container.appendChild(section); + + const pinnedContainer = document.getElementById('vertical-pinned-tabs-container'); + const pinnedSection = this._createWorkspaceSection(workspace); + this._organizeTabsToWorkspaceSections(workspace, section, pinnedSection, tabs); + section.appendChild(perifery.cloneNode(true)); + pinnedSection.appendChild( + window.MozXULElement.parseXULToFragment(` + + `) + ); + pinnedContainer.appendChild(pinnedSection); + + const workspaceIndicator = this._createWorkspaceSection(workspace); + workspaceIndicator.classList.add('zen-current-workspace-indicator'); + workspaceIndicator.appendChild(window.MozXULElement.parseXULToFragment(this.workspaceIndicatorXUL)); + document.getElementById('zen-current-workspace-indicator-container').appendChild(workspaceIndicator); + this.initIndicatorContextMenu(workspaceIndicator); + } + + _organizeTabsToWorkspaceSections(workspace, section, pinnedSection, tabs) { const workspaceTabs = Array.from(tabs).filter((tab) => tab.getAttribute('zen-workspace-id') === workspace.uuid); for (const tab of workspaceTabs) { - section.appendChild(tab); + // remove tab from list + tabs.splice(tabs.indexOf(tab), 1); + if (tab.pinned) { + pinnedSection.appendChild(tab); + } else { + section.appendChild(tab); + } } this.tabContainer._invalidateCachedTabs(); - } + } initializeWorkspaceNavigation() { this._setupAppCommandHandlers(); @@ -462,11 +535,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { console.error('ZenWorkspaces: Error initializing theme picker', e); } } - this.initIndicatorContextMenu(); } - initIndicatorContextMenu() { - const indicator = document.getElementById('zen-current-workspace-indicator'); + initIndicatorContextMenu(indicator) { const th = (event) => { event.preventDefault(); event.stopPropagation(); @@ -780,7 +851,6 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { if (!browser.ZenWorkspaces.workspaceEnabled) { return; } - await browser.ZenWorkspaces.updateWorkspaceIndicator(); let workspaceList = browser.document.getElementById('PanelUI-zen-workspaces-list'); const createWorkspaceElement = (workspace) => { let element = browser.document.createXULElement('toolbarbutton'); @@ -1074,7 +1144,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { if (!this.workspaceEnabled) { return; } - let target = event.target.closest('#zen-current-workspace-indicator') || document.getElementById('zen-workspaces-button'); + let target = event.target.closest('.zen-current-workspace-indicator') || document.getElementById('zen-workspaces-button'); let panel = document.getElementById('PanelUI-zen-workspaces'); await this._propagateWorkspaceData({ ignoreStrip: true, @@ -1231,13 +1301,25 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } } + moveTabToWorkspace(tab, workspaceID) { + if (tab.getAttribute('zen-workspace-id') === workspaceID) { + return; + } + 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'); + if (container) { + container.insertBefore(tab, container.firstChild); + } + } + _prepareNewWorkspace(window) { document.documentElement.setAttribute('zen-workspace-id', window.uuid); let tabCount = 0; for (let tab of gBrowser.tabs) { const isEssential = tab.getAttribute('zen-essential') === 'true'; if (!tab.hasAttribute('zen-workspace-id') && !tab.pinned && !isEssential) { - tab.setAttribute('zen-workspace-id', window.uuid); + this.moveTabToWorkspace(tab, window.uuid); tabCount++; } } @@ -1250,7 +1332,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); + this.moveTabToWorkspace(tab, window.uuid); } } @@ -1323,7 +1405,6 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { await this._performWorkspaceChange(window, ...args); } finally { this._inChangingWorkspace = false; - this.tabContainer.removeAttribute('dont-animate-tabs'); } } @@ -1359,87 +1440,125 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { const workspaces = await this._workspaces(); // Refresh tab cache + gBrowser.verticalPinnedTabsContainer = this.pinnedTabsContainer; + gBrowser.tabContainer.verticalPinnedTabsContainer = this.pinnedTabsContainer; this.tabContainer._invalidateCachedTabs(); - - if (previousWorkspace && !onInit && !this._animatingChange) { - await this._animateTabs(previousWorkspace, window); - } + await this._organizeWorkspaceStripLocations(previousWorkspace); // First pass: Handle tab visibility and workspace ID assignment - const visibleTabs = this._processTabVisibility(window.uuid, containerId, workspaces); + this._processTabVisibility(window.uuid, containerId, workspaces); // Second pass: Handle tab selection - await this._handleTabSelection(window, onInit, visibleTabs, containerId, workspaces, previousWorkspace.uuid); + this.tabContainer._invalidateCachedTabs(); + await this._handleTabSelection(window, onInit, containerId, workspaces, previousWorkspace.uuid); + this.tabContainer._updateVerticalPinnedTabs(); // Update UI and state await this._updateWorkspaceState(window, onInit); - } get _animateTabsElements() { const selector = `#zen-browser-tabs-wrapper`; - const extraSelector = `#zen-current-workspace-indicator`; + const extraSelector = `.zen-current-workspace-indicator`; return [...this.tabContainer.querySelectorAll(selector), ...this.tabContainer.querySelectorAll(extraSelector)]; } - async _animateTabs(previousWorkspace, newWorkspace) { - const newWorkspaceContainer = this.tabContainer; - const previousWorkspaceContainer = document.querySelector(`[zen-workspace-id="${previousWorkspace.uuid}"]`); + _updateMarginTopPinnedTabs(arrowscrollbox, pinnedContainer) { + if (arrowscrollbox) { + arrowscrollbox.style.marginTop = pinnedContainer.getBoundingClientRect().height + 'px'; + } + } - const newWorkspaceLeft = newWorkspaceContainer.getBoundingClientRect().left; - gZenUIManager.motion.animate( - newWorkspaceContainer, - { - transform: [`translateX(${newWorkspaceLeft}px)`, 'translateX(0)'], - }, - { - type: 'spring', - bounce: 0, - duration: 0.12, + async _organizeWorkspaceStripLocations(workspace) { + const workspaces = await this._workspaces(); + let workspaceIndex = workspaces.workspaces.findIndex((w) => w.uuid === workspace.uuid); + this._fixIndicatorsNames(workspaces); + for (const otherWorkspace of workspaces.workspaces) { + const selector = `.zen-workspace-tabs-section[zen-workspace-id="${otherWorkspace.uuid}"]`; + const newTransform = -(workspaceIndex - workspaces.workspaces.indexOf(otherWorkspace)) * 100; + for (const container of document.querySelectorAll(selector)) { + container.style.transform = `translateX(${newTransform}%)`; + container.style.opacity = !newTransform; } - ); - gZenUIManager.motion.animate( - previousWorkspaceContainer, - { - transform: ['translateX(0)', `translateX(-${newWorkspaceLeft}px)`], - }, - { - type: 'spring', - bounce: 0, - duration: 0.12, + 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); + } + } + + updateWorkspaceIndicator(currentWorkspace, workspaceIndicator) { + if (!workspaceIndicator) { + return; + } + const indicatorName = workspaceIndicator.querySelector('.zen-current-workspace-indicator-name'); + const indicatorIcon = workspaceIndicator.querySelector('.zen-current-workspace-indicator-icon'); + + if (this.workspaceHasIcon(currentWorkspace)) { + indicatorIcon.removeAttribute('no-icon'); + } else { + indicatorIcon.setAttribute('no-icon', 'true'); + } + indicatorIcon.textContent = this.getWorkspaceIcon(currentWorkspace); + indicatorName.textContent = currentWorkspace.name; + } + + _fixIndicatorsNames(workspaces) { + for (const workspace of workspaces.workspaces) { + const workspaceIndicator = document.querySelector( + `#zen-current-workspace-indicator-container .zen-workspace-tabs-section[zen-workspace-id="${workspace.uuid}"]` + ); + this.updateWorkspaceIndicator(workspace, workspaceIndicator); + } + } + + async _animateTabs(newWorkspace, shouldAnimate) { + this._animatingChange = true; + const animations = []; + const workspaces = await this._workspaces(); + const newWorkspaceIndex = workspaces.workspaces.findIndex((w) => w.uuid === newWorkspace.uuid); + for (const element of document.querySelectorAll('.zen-workspace-tabs-section')) { + const existingTransform = element.style.transform; + const elementWorkspaceId = element.getAttribute('zen-workspace-id'); + const elementWorkspaceIndex = workspaces.workspaces.findIndex((w) => w.uuid === elementWorkspaceId); + const offset = -(newWorkspaceIndex - elementWorkspaceIndex) * 100; + const newTransform = `translateX(${offset}%)`; + if (shouldAnimate) { + animations.push( + gZenUIManager.motion.animate( + element, + { + transform: existingTransform ? [existingTransform, newTransform] : newTransform, + // -0 to convert to number + opacity: [!!offset - 0, !offset - 0], + }, + { + type: 'spring', + bounce: 0, + duration: 0.3, + } + ) + ); } - ); + if (offset === 0) { + element.setAttribute('active', 'true'); + } else { + element.removeAttribute('active'); + } + } + await Promise.all(animations); + this._animatingChange = false; } _processTabVisibility(workspaceUuid, containerId, workspaces) { - const visibleTabs = new Set(); - const lastSelectedTab = this._lastSelectedWorkspaceTabs[workspaceUuid]; - - this.tabContainer.setAttribute('dont-animate-tabs', 'true'); for (const tab of gBrowser.tabs) { - const tabWorkspaceId = tab.getAttribute('zen-workspace-id'); - const isEssential = tab.getAttribute('zen-essential') === 'true'; - - // Always hide last selected tabs from other workspaces - if (lastSelectedTab === tab && tabWorkspaceId !== workspaceUuid && !isEssential) { - gBrowser.hideTab(tab, undefined, true); - continue; - } - - if (this._shouldShowTab(tab, workspaceUuid, containerId, workspaces)) { - gBrowser.showTab(tab); - visibleTabs.add(tab); - - // Assign workspace ID if needed - if (!tabWorkspaceId && !isEssential) { - tab.setAttribute('zen-workspace-id', workspaceUuid); - } - } else { + if (!this._shouldShowTab(tab, workspaceUuid, containerId, workspaces)) { gBrowser.hideTab(tab, undefined, true); + } else if (tab.hasAttribute('zen-essential')) { + gBrowser.showTab(tab, undefined, true); } } - - return visibleTabs; } _shouldShowTab(tab, workspaceUuid, containerId, workspaces) { @@ -1470,15 +1589,15 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { // For non-essential tabs (both normal and pinned) if (!tabWorkspaceId) { // Assign workspace ID to tabs without one - tab.setAttribute('zen-workspace-id', workspaceUuid); + this.moveTabToWorkspace(tab, workspaceUuid); return true; } // Show if tab belongs to current workspace - return tabWorkspaceId === workspaceUuid; + return true; } - async _handleTabSelection(window, onInit, visibleTabs, containerId, workspaces, previousWorkspaceId) { + async _handleTabSelection(window, onInit, containerId, workspaces, previousWorkspaceId) { const currentSelectedTab = gBrowser.selectedTab; const oldWorkspaceId = previousWorkspaceId; const lastSelectedTab = this._lastSelectedWorkspaceTabs[window.uuid]; @@ -1489,29 +1608,18 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } let tabToSelect = null; - - // If current tab is visible in new workspace, keep it - if (this._shouldShowTab(currentSelectedTab, window.uuid, containerId, workspaces) && visibleTabs.has(currentSelectedTab)) { - tabToSelect = currentSelectedTab; - } // Try last selected tab if it is visible - else if ( - lastSelectedTab && - this._shouldShowTab(lastSelectedTab, window.uuid, containerId, workspaces) && - visibleTabs.has(lastSelectedTab) - ) { + if (lastSelectedTab && this._shouldShowTab(lastSelectedTab, window.uuid, containerId, workspaces)) { tabToSelect = lastSelectedTab; } // Find first suitable tab else { - tabToSelect = Array.from(visibleTabs).find((tab) => !tab.pinned); - if (!tabToSelect && visibleTabs.length) { - tabToSelect = Array.from(visibleTabs)[visibleTabs.length - 1]; + tabToSelect = gBrowser.visibleTabs.find((tab) => !tab.pinned); + if (!tabToSelect && gBrowser.visibleTabs.length) { + tabToSelect = gBrowser.visibleTabs[gBrowser.visibleTabs.length - 1]; } } - const previousSelectedTab = gBrowser.selectedTab; - // If we found a tab to select, select it if (tabToSelect) { gBrowser.selectedTab = tabToSelect; @@ -1522,17 +1630,15 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { gBrowser.selectedTab = newTab; this._lastSelectedWorkspaceTabs[window.uuid] = newTab; } - - // After selecting the new tab, hide the previous selected tab if it shouldn't be visible in the new workspace - if (!this._shouldShowTab(previousSelectedTab, window.uuid, containerId, workspaces)) { - gBrowser.hideTab(previousSelectedTab, undefined, true); - } } async _updateWorkspaceState(window, onInit) { // Update document state document.documentElement.setAttribute('zen-workspace-id', window.uuid); + // Recalculate new tab observers + gBrowser.tabContainer.observe(null, 'nsPref:changed', 'privacy.userContext.enabled'); + // Update workspace UI await this._updateWorkspacesChangeContextMenu(); document.getElementById('tabbrowser-tabs')._positionPinnedTabs(); @@ -1546,6 +1652,8 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } } + await this._animateTabs(window, !onInit && !this._animatingChange); + // Reset bookmarks this._invalidateBookmarkContainers(); @@ -1563,22 +1671,6 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } } - async updateWorkspaceIndicator() { - // Update current workspace indicator - const currentWorkspace = await this.getActiveWorkspace(); - if (!currentWorkspace) return; - const indicatorName = document.getElementById('zen-current-workspace-indicator-name'); - const indicatorIcon = document.getElementById('zen-current-workspace-indicator-icon'); - - if (this.workspaceHasIcon(currentWorkspace)) { - indicatorIcon.removeAttribute('no-icon'); - } else { - indicatorIcon.setAttribute('no-icon', 'true'); - } - indicatorIcon.textContent = this.getWorkspaceIcon(currentWorkspace); - indicatorName.textContent = currentWorkspace.name; - } - async _updateWorkspacesChangeContextMenu() { const workspaces = await this._workspaces(); @@ -1612,6 +1704,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { theme: ZenThemePicker.getTheme([]), }; this._prepareNewWorkspace(window); + const perifery = document.querySelector('#tabbrowser-arrowscrollbox-periphery[hidden]'); + preifery?.removeAttribute('hidden'); + this._createWorkspaceTabsSection(window, [], perifery); + preifery.setAttribute('hidden', 'true'); return window; } @@ -1622,9 +1718,23 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { let workspaceData = this._createWorkspaceData(name, isDefault, icon); await this.saveWorkspace(workspaceData); await this.changeWorkspace(workspaceData); + this.registerPinnedResizeObserver(); return workspaceData; } + onPinnedTabsResize(entries) { + if (!this.workspaceEnabled) { + return; + } + for (const entry of entries) { + const workspaceId = entry.target.getAttribute('zen-workspace-id'); + const arrowScrollbox = document.querySelector( + `#tabbrowser-arrowscrollbox .zen-workspace-tabs-section[zen-workspace-id="${workspaceId}"]` + ); + this._updateMarginTopPinnedTabs(arrowScrollbox, entry.target); + } + } + async onTabBrowserInserted(event) { let tab = event.originalTarget; const isEssential = tab.getAttribute('zen-essential') === 'true'; @@ -1666,6 +1776,30 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } } + makeSurePinTabIsInCorrectPosition() { + const tabsInsidePinTab = Array.from(this.pinnedTabsContainer.parentElement.children).filter( + (child) => child.tagName === 'tab' + ); + let changed = false; + for (const tab of tabsInsidePinTab) { + if (tab.getAttribute('zen-essential') === 'true') { + continue; + } + const workspaceId = tab.getAttribute('zen-workspace-id'); + if (!workspaceId) { + continue; + } + const contaienr = document.querySelector( + `#vertical-pinned-tabs-container .zen-workspace-tabs-section[zen-workspace-id="${workspaceId}"]` + ); + contaienr.insertBefore(tab, contaienr.firstChild); + changed = true; + } + if (changed) { + gBrowser.tabContainer._invalidateCachedTabs(); + } + } + // Context menu management _contextMenuId = null; @@ -1801,7 +1935,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { document.getElementById('tabContextMenu').hidePopup(); const previousWorkspaceID = document.documentElement.getAttribute('zen-workspace-id'); for (let tab of tabs) { - tab.setAttribute('zen-workspace-id', workspaceID); + this.moveTabToWorkspace(tab, workspaceID); if (this._lastSelectedWorkspaceTabs[previousWorkspaceID] === tab) { // This tab is no longer the last selected tab in the previous workspace because it's being moved to // the current workspace diff --git a/src/browser/components/tabbrowser/content/tabbrowser-js.patch b/src/browser/components/tabbrowser/content/tabbrowser-js.patch index 5d2f2730d..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..f7c02c14498b4ec5fcf5521480c88abac25a2283 100644 +index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..c90119b4b248887fd8612beb9aac83c6eeb57088 100644 --- a/browser/components/tabbrowser/content/tabbrowser.js +++ b/browser/components/tabbrowser/content/tabbrowser.js @@ -406,11 +406,39 @@ @@ -49,7 +49,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..f7c02c14498b4ec5fcf5521480c88aba if (this.tabContainer.verticalMode) { this._handleTabMove(aTab, () => - this.verticalPinnedTabsContainer.appendChild(aTab) -+ aTab.hasAttribute("zen-essential") ? document.getElementById("zen-essentials-container").appendChild(aTab) : this.verticalPinnedTabsContainer.appendChild(aTab) ++ aTab.hasAttribute("zen-essential") ? document.getElementById("zen-essentials-container").appendChild(aTab) : this.verticalPinnedTabsContainer.insertBefore(aTab, this.verticalPinnedTabsContainer.lastChild) ); } else { - this.moveTabTo(aTab, this.pinnedTabCount, { forceStandaloneTab: true }); diff --git a/src/browser/components/tabbrowser/content/tabs-js.patch b/src/browser/components/tabbrowser/content/tabs-js.patch index b0a668a3c..149134733 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..ef532d6b5d311cab5bc573c2d0aae6ceab5c1dcf 100644 +index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67709dae7d 100644 --- a/browser/components/tabbrowser/content/tabs.js +++ b/browser/components/tabbrowser/content/tabs.js @@ -94,7 +94,7 @@ @@ -101,6 +101,15 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ef532d6b5d311cab5bc573c2d0aae6ce ) { delete draggedTab._dragData; return; +@@ -1478,7 +1491,7 @@ + } + + get newTabButton() { +- return this.querySelector("#tabs-newtab-button"); ++ return ZenWorkspaces.activeWorkspaceStrip.querySelector("#tabs-newtab-button"); + } + + get verticalMode() { @@ -1498,7 +1511,7 @@ if (this.#allTabs) { return this.#allTabs; @@ -110,7 +119,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ef532d6b5d311cab5bc573c2d0aae6ce // remove arrowScrollbox periphery element children.pop(); -@@ -1512,14 +1525,24 @@ +@@ -1512,14 +1525,28 @@ } this.#allTabs = [ @@ -126,6 +135,10 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ef532d6b5d311cab5bc573c2d0aae6ce + // insert right after the parent tab + this.#allTabs.splice(Math.min(i + 1, lastPinnedTabIdx), 0, glanceTab); + i++; ++ } else if (this.#allTabs[i].classList.contains("vertical-pinned-tabs-container-separator")) { ++ // remove the separator from the list ++ this.#allTabs.splice(i, 1); ++ i--; + } + } return this.#allTabs; @@ -137,16 +150,20 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ef532d6b5d311cab5bc573c2d0aae6ce return children.filter(node => node.tagName == "tab-group"); } -@@ -1577,7 +1600,7 @@ - let verticalPinnedTabsContainer = document.getElementById( - "vertical-pinned-tabs-container" - ); +@@ -1574,10 +1601,8 @@ + return this.#focusableItems; + } + +- let verticalPinnedTabsContainer = document.getElementById( +- "vertical-pinned-tabs-container" +- ); - let children = Array.from(this.arrowScrollbox.children); ++ let verticalPinnedTabsContainer = this.verticalPinnedTabsContainer; + let children = Array.from(ZenWorkspaces.tabboxChildren); let focusableItems = []; for (let child of children) { -@@ -1593,6 +1616,7 @@ +@@ -1593,6 +1618,7 @@ } this.#focusableItems = [ @@ -154,7 +171,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ef532d6b5d311cab5bc573c2d0aae6ce ...verticalPinnedTabsContainer.children, ...focusableItems, ]; -@@ -1617,8 +1641,8 @@ +@@ -1617,8 +1643,8 @@ #isContainerVerticalPinnedExpanded(tab) { return ( this.verticalMode && @@ -165,7 +182,25 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ef532d6b5d311cab5bc573c2d0aae6ce ); } -@@ -1816,7 +1840,7 @@ +@@ -1633,7 +1659,7 @@ + + if (node == null) { + // We have a container for non-tab elements at the end of the scrollbox. +- node = this.arrowScrollbox.lastChild; ++ node = ZenWorkspaces.activeWorkspaceStrip.lastChild; + } + + node.before(tab); +@@ -1733,7 +1759,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. +- const newTab = document.getElementById("new-tab-button"); ++ const newTab = ZenWorkspaces.activeWorkspaceStrip.querySelector("#tabs-newtab-button"); + const newTab2 = this.newTabButton; + const newTabVertical = document.getElementById( + "vertical-tabs-newtab-button" +@@ -1816,7 +1842,7 @@ let rect = ele => { return window.windowUtils.getBoundsWithoutFlushing(ele); }; @@ -174,7 +209,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ef532d6b5d311cab5bc573c2d0aae6ce if (tab && rect(tab).width <= this._tabClipWidth) { this.setAttribute("closebuttons", "activetab"); } else { -@@ -1832,6 +1856,7 @@ +@@ -1832,6 +1858,7 @@ this.arrowScrollbox.ensureElementIsVisible(selectedTab, aInstant); } @@ -182,7 +217,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ef532d6b5d311cab5bc573c2d0aae6ce selectedTab._notselectedsinceload = false; } -@@ -1843,7 +1868,7 @@ +@@ -1843,7 +1870,7 @@ return; } @@ -191,7 +226,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ef532d6b5d311cab5bc573c2d0aae6ce if (!tabs.length) { return; } -@@ -1879,7 +1904,7 @@ +@@ -1879,7 +1906,7 @@ if (isEndTab && !this._hasTabTempMaxWidth) { return; } @@ -200,7 +235,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ef532d6b5d311cab5bc573c2d0aae6ce // 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 +1919,7 @@ +@@ -1894,7 +1921,7 @@ let tabsToReset = []; for (let i = numPinned; i < tabs.length; i++) { let tab = tabs[i]; @@ -209,22 +244,40 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ef532d6b5d311cab5bc573c2d0aae6ce if (!isEndTab) { // keep tabs the same width tab.style.transition = "none"; -@@ -1965,11 +1990,11 @@ - ); +@@ -1960,16 +1987,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. +- let verticalTabsContainer = document.getElementById( +- "vertical-pinned-tabs-container" +- ); ++ let verticalTabsContainer = this.verticalPinnedTabsContainer; let numPinned = gBrowser.pinnedTabCount; - if (gBrowser.pinnedTabCount !== verticalTabsContainer.children.length) { - let tabs = this.visibleTabs; -+ if (gBrowser.pinnedTabCount !== (verticalTabsContainer.children.length + document.getElementById("zen-essentials-container").children.length)) { ++ ZenWorkspaces.makeSurePinTabIsInCorrectPosition(); ++ if (gBrowser.pinnedTabCount !== (verticalTabsContainer.children.length - 1 + document.getElementById("zen-essentials-container").children.length)) { + let tabs = this.allTabs.filter(tab => !tab.hasAttribute("zen-glance-tab")); for (let i = 0; i < numPinned; i++) { tabs[i].style.marginInlineStart = ""; - verticalTabsContainer.appendChild(tabs[i]); -+ tabs[i].hasAttribute("zen-essential") ? document.getElementById("zen-essentials-container").appendChild(tabs[i]) : verticalTabsContainer.appendChild(tabs[i]); ++ tabs[i].hasAttribute("zen-essential") ? document.getElementById("zen-essentials-container").appendChild(tabs[i]) : verticalTabsContainer.insertBefore(tabs[i], verticalTabsContainer.lastChild); } } -@@ -1992,8 +2017,8 @@ +@@ -1977,9 +2003,7 @@ + } + + _resetVerticalPinnedTabs() { +- let verticalTabsContainer = document.getElementById( +- "vertical-pinned-tabs-container" +- ); ++ let verticalTabsContainer = this.verticalPinnedTabsContainer; + + if (!verticalTabsContainer.children.length) { + return; +@@ -1992,8 +2016,8 @@ } _positionPinnedTabs() { @@ -235,7 +288,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ef532d6b5d311cab5bc573c2d0aae6ce let absPositionHorizontalTabs = this.overflowing && tabs.length > numPinned && numPinned > 0; -@@ -2074,7 +2099,7 @@ +@@ -2074,7 +2098,7 @@ return; } @@ -244,7 +297,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ef532d6b5d311cab5bc573c2d0aae6ce let directionX = screenX > dragData.animLastScreenX; let directionY = screenY > dragData.animLastScreenY; -@@ -2257,9 +2282,9 @@ +@@ -2257,9 +2281,9 @@ } let pinned = draggedTab.pinned; @@ -257,7 +310,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ef532d6b5d311cab5bc573c2d0aae6ce pinned ? numPinned : undefined ); -@@ -2502,8 +2527,9 @@ +@@ -2502,8 +2526,9 @@ ); } @@ -269,7 +322,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ef532d6b5d311cab5bc573c2d0aae6ce return; } -@@ -2668,9 +2694,9 @@ +@@ -2668,9 +2693,9 @@ function newIndex(aTab, index) { // Don't allow mixing pinned and unpinned tabs. if (aTab.pinned) { @@ -281,7 +334,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ef532d6b5d311cab5bc573c2d0aae6ce } } -@@ -2754,7 +2780,7 @@ +@@ -2754,7 +2779,7 @@ } _notifyBackgroundTab(aTab) { @@ -290,7 +343,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ef532d6b5d311cab5bc573c2d0aae6ce return; } -@@ -2772,12 +2798,14 @@ +@@ -2772,12 +2797,14 @@ selectedTab = { left: selectedTab.left, right: selectedTab.right, @@ -306,7 +359,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ef532d6b5d311cab5bc573c2d0aae6ce selectedTab, ]; }) -@@ -2794,8 +2822,11 @@ +@@ -2794,8 +2821,11 @@ delete this._lastTabToScrollIntoView; // Is the new tab already completely visible? if ( @@ -320,7 +373,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ef532d6b5d311cab5bc573c2d0aae6ce ) { return; } -@@ -2803,21 +2834,29 @@ +@@ -2803,21 +2833,29 @@ if (this.arrowScrollbox.smoothScroll) { // Can we make both the new tab and the selected tab completely visible? if ( diff --git a/src/browser/themes/shared/tabbrowser/tabs-css.patch b/src/browser/themes/shared/tabbrowser/tabs-css.patch index 93e6cab24..65ff40457 100644 --- a/src/browser/themes/shared/tabbrowser/tabs-css.patch +++ b/src/browser/themes/shared/tabbrowser/tabs-css.patch @@ -1,5 +1,5 @@ diff --git a/browser/themes/shared/tabbrowser/tabs.css b/browser/themes/shared/tabbrowser/tabs.css -index 96f930638c04c7ddcc8dc1a7fe4dce8b12a325e6..64487674de1afb711258a36757508cd9b741fcd9 100644 +index 96f930638c04c7ddcc8dc1a7fe4dce8b12a325e6..9e11e715ade485c33ba4c8f719b41002f3008dde 100644 --- a/browser/themes/shared/tabbrowser/tabs.css +++ b/browser/themes/shared/tabbrowser/tabs.css @@ -33,7 +33,7 @@ @@ -64,6 +64,15 @@ index 96f930638c04c7ddcc8dc1a7fe4dce8b12a325e6..64487674de1afb711258a36757508cd9 direction: rtl; mask-image: linear-gradient(to right, transparent, black var(--tab-label-mask-size)); } +@@ -1135,7 +1133,7 @@ + } + } + +-#tabbrowser-arrowscrollbox[orient="vertical"] > #tabbrowser-arrowscrollbox-periphery > #tabs-newtab-button, ++#tabbrowser-arrowscrollbox[orient="vertical"] #tabbrowser-arrowscrollbox-periphery > #tabs-newtab-button, + #vertical-tabs-newtab-button { + appearance: none; + min-height: var(--tab-min-height); @@ -1146,7 +1144,7 @@ margin-inline: var(--tab-inner-inline-margin); @@ -73,6 +82,15 @@ index 96f930638c04c7ddcc8dc1a7fe4dce8b12a325e6..64487674de1afb711258a36757508cd9 } &:hover { +@@ -1170,7 +1168,7 @@ + * flex container. #tabs-newtab-button is a child of the arrowscrollbox where + * we don't want a gap (between tabs), so we have to add some margin. + */ +-#tabbrowser-arrowscrollbox[orient="vertical"] > #tabbrowser-arrowscrollbox-periphery > #tabs-newtab-button { ++#tabbrowser-arrowscrollbox[orient="vertical"] #tabbrowser-arrowscrollbox-periphery > #tabs-newtab-button { + margin-block: var(--tab-block-margin); + } + @@ -1194,7 +1192,6 @@ } diff --git a/src/toolkit/content/widgets/arrowscrollbox-js.patch b/src/toolkit/content/widgets/arrowscrollbox-js.patch index 28739a036..ebfbd2dec 100644 --- a/src/toolkit/content/widgets/arrowscrollbox-js.patch +++ b/src/toolkit/content/widgets/arrowscrollbox-js.patch @@ -1,25 +1,7 @@ diff --git a/toolkit/content/widgets/arrowscrollbox.js b/toolkit/content/widgets/arrowscrollbox.js -index 328c770d275ebbaada8a44438eaf738b1a62d985..070439e26bfe6a2299aa4b82ee4c434e143e1a20 100644 +index 328c770d275ebbaada8a44438eaf738b1a62d985..95460108c6356408170b8a4a40d55a8f0621756b 100644 --- a/toolkit/content/widgets/arrowscrollbox.js +++ b/toolkit/content/widgets/arrowscrollbox.js -@@ -15,7 +15,7 @@ - static get inheritedAttributes() { - return { - "#scrollbutton-up": "disabled=scrolledtostart", -- scrollbox: "orient,align,pack,dir,smoothscroll", -+ scrollbox: "align,pack,dir,smoothscroll", - "#scrollbutton-down": "disabled=scrolledtoend", - }; - } -@@ -26,7 +26,7 @@ - - - -- -+ - - - @@ -98,6 +98,7 @@ let slot = this.shadowRoot.querySelector("slot");