diff --git a/.github/workflows/update-submodules.yml b/.github/workflows/update-submodules.yml deleted file mode 100644 index 18fa6cc26..000000000 --- a/.github/workflows/update-submodules.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: Update Components Submodules - -on: - push: - branches: - - dev - workflow_dispatch: - workflow_call: - -jobs: - update-submodules: - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, '[skip ci]')" - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - submodules: recursive - token: ${{ secrets.DEPLOY_KEY }} - - - name: Update submodules - run: | - git submodule update --remote --merge - - - name: Commit - uses: stefanzweifel/git-auto-commit-action@v5 - with: - commit_message: '[skip ci] 📦 Update submodules' - commit_user_name: Zen Browser Robot - commit_user_email: zen-browser-auto@users.noreply.github.com diff --git a/configs/common/mozconfig b/configs/common/mozconfig index f840e768c..fce7a4692 100644 --- a/configs/common/mozconfig +++ b/configs/common/mozconfig @@ -9,7 +9,7 @@ ac_add_options --with-l10n-base="${topsrcdir}/browser/locales" export MOZ_USER_DIR="${name}" export MOZ_APP_BASENAME=Zen export MOZ_APP_PROFILE=${binName} -export MOZ_APP_DISPLAYNAME="${name}" +export MOZ_APP_DISPLAYNAME="Zen" export MOZ_BRANDING_DIRECTORY=${brandingDir} export MOZ_OFFICIAL_BRANDING_DIRECTORY=${brandingDir} diff --git a/src/browser/app/profile/zen-browser.js b/src/browser/app/profile/zen-browser.js index 35b747a11..e0d21b352 100644 --- a/src/browser/app/profile/zen-browser.js +++ b/src/browser/app/profile/zen-browser.js @@ -128,6 +128,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 @@ -426,7 +430,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); diff --git a/src/browser/base/content/ZenStartup.mjs b/src/browser/base/content/ZenStartup.mjs index a09e51f47..88e4fad4b 100644 --- a/src/browser/base/content/ZenStartup.mjs +++ b/src/browser/base/content/ZenStartup.mjs @@ -3,11 +3,9 @@ var ZenStartup = { init() { this.openWatermark(); - window.SessionStore.promiseInitialized.then(() => { - this._changeSidebarLocation(); - this._zenInitBrowserLayout(); - this._initSearchBar(); - }); + this._changeSidebarLocation(); + this._zenInitBrowserLayout(); + this._initSearchBar(); }, _zenInitBrowserLayout() { @@ -85,7 +83,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 @@ -94,8 +92,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/content/ZenUIManager.mjs b/src/browser/base/content/ZenUIManager.mjs index 2bb409f25..de6c363ae 100644 --- a/src/browser/base/content/ZenUIManager.mjs +++ b/src/browser/base/content/ZenUIManager.mjs @@ -14,9 +14,7 @@ var gZenUIManager = { return ChromeUtils.importESModule('chrome://browser/content/zen-vendor/motion.min.mjs', { global: 'current' }); }); - new ResizeObserver(gZenCommonActions.throttle(this.updateTabsToolbar.bind(this), this.sidebarHeightThrottle)).observe( - document.getElementById('TabsToolbar') - ); + new ResizeObserver(this.updateTabsToolbar.bind(this)).observe(document.getElementById('TabsToolbar')); new ResizeObserver( gZenCommonActions.throttle( @@ -27,6 +25,7 @@ var gZenUIManager = { SessionStore.promiseAllWindowsRestored.then(() => { this._hasLoadedDOM = true; + this.updateTabsToolbar(); }); window.addEventListener('TabClose', this.onTabClose.bind(this)); @@ -35,7 +34,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) { @@ -62,7 +61,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; }, @@ -148,8 +147,8 @@ var gZenUIManager = { this.__currentPopupTrackElement = null; }, - get newtabButton() { - return ZenWorkspaces.activeWorkspaceStrip.querySelector('#tabs-newtab-button'); + get newtabButtons() { + return document.querySelectorAll('#tabs-newtab-button'); }, _prevUrlbarLabel: null, @@ -169,7 +168,9 @@ var gZenUIManager = { this._prevUrlbarLabel = gURLBar._untrimmedValue; gURLBar._zenHandleUrlbarClose = this.handleUrlbarClose.bind(this); gURLBar.setAttribute('zen-newtab', true); - this.newtabButton.setAttribute('in-urlbar', true); + for (const button of this.newtabButtons) { + button.setAttribute('in-urlbar', true); + } document.getElementById('Browser:OpenLocation').doCommand(); gURLBar.search(this._lastSearch); return true; @@ -187,7 +188,9 @@ var gZenUIManager = { gURLBar.removeAttribute('zen-newtab'); this._lastTab._visuallySelected = true; this._lastTab = null; - this.newtabButton.removeAttribute('in-urlbar'); + for (const button of this.newtabButtons) { + button.removeAttribute('in-urlbar'); + } if (onSwitch) { this.clearUrlbarData(); } else { @@ -240,7 +243,7 @@ var gZenVerticalTabsManager = { window.addEventListener('customizationstarting', this._preCustomize.bind(this)); window.addEventListener('aftercustomization', this._postCustomize.bind(this)); - window.addEventListener('DOMContentLoaded', updateEvent, { once: true }); + this._updateEvent(); if (!this.isWindowsStyledButtons) { document.documentElement.setAttribute('zen-window-buttons-reversed', true); @@ -415,7 +418,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 ? '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) { @@ -569,6 +575,7 @@ var gZenVerticalTabsManager = { } catch (e) { console.error(e); } + gZenUIManager.updateTabsToolbar(); this._isUpdating = false; }, diff --git a/src/browser/base/content/navigator-toolbox-inc-xhtml.patch b/src/browser/base/content/navigator-toolbox-inc-xhtml.patch index bc2ef52de..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..340475da315e67b2dd4f93567547cde703a90ee8 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 @@ @@ -40,17 +40,18 @@ index a0a382643a2f74b6d789f3641ef300eed202d5e9..340475da315e67b2dd4f93567547cde7 + + -+ ++ ++ + @@ -83,7 +85,7 @@ index a0a382643a2f74b6d789f3641ef300eed202d5e9..340475da315e67b2dd4f93567547cde7 diff --git a/src/browser/base/content/navigator-toolbox-js.patch b/src/browser/base/content/navigator-toolbox-js.patch index 59e00cfd2..721a1e01b 100644 --- a/src/browser/base/content/navigator-toolbox-js.patch +++ b/src/browser/base/content/navigator-toolbox-js.patch @@ -1,5 +1,5 @@ diff --git a/browser/base/content/navigator-toolbox.js b/browser/base/content/navigator-toolbox.js -index 64ded8fb2c08f1dbfec8fe08ab427a24b53f1169..3434a833c4d1220554b4df6eeeed83f500c6f812 100644 +index 64ded8fb2c08f1dbfec8fe08ab427a24b53f1169..9e1e888554279b6e1df3bc1cb907afd2ccb330ca 100644 --- a/browser/base/content/navigator-toolbox.js +++ b/browser/base/content/navigator-toolbox.js @@ -8,7 +8,7 @@ @@ -15,7 +15,7 @@ index 64ded8fb2c08f1dbfec8fe08ab427a24b53f1169..3434a833c4d1220554b4df6eeeed83f5 #reload-button , #urlbar-go-button, #reader-mode-button, -+ #zen-browser-tabs-wrapper, ++ #zen-tabs-wrapper, #picture-in-picture-button, #shopping-sidebar-button, #urlbar-zoom-button, @@ -23,7 +23,7 @@ index 64ded8fb2c08f1dbfec8fe08ab427a24b53f1169..3434a833c4d1220554b4df6eeeed83f5 case "vertical-tabs-newtab-button": case "tabs-newtab-button": case "new-tab-button": -+ case "zen-browser-tabs-wrapper": ++ case "zen-tabs-wrapper": gBrowser.handleNewTabMiddleClick(element, event); break; 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 2f30ea86a..0ca35b4f0 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; } @@ -281,10 +280,6 @@ } } - &[selected] .tab-background { - backdrop-filter: blur(10px); - } - @media (-moz-bool-pref: 'zen.tabs.dim-pending') { &[pending='true'] .tab-icon-image { opacity: 0.5; @@ -327,13 +322,18 @@ /* On essentials, glance tabs are floating */ &[zen-essential='true'] .tabbrowser-tab { position: absolute; - top: 4px; - right: 4px; - --tab-collapsed-width: 35px; + top: 0px; + right: 0px; + --tab-collapsed-width: 34px; --tab-min-height: 16px; width: var(--tab-collapsed-width) !important; z-index: 1; pointer-events: none; + & .tab-background { + /* Solid colors because we don't want to show the background */ + background: light-dark(rgb(249, 249, 249), rgb(63, 63, 63)) !important; + border: 2px solid light-dark(rgba(0, 0, 0, 0.4), rgba(255, 255, 255, 0.4)); + } } } } @@ -366,20 +366,25 @@ } } -#zen-browser-tabs-wrapper { +#zen-tabs-wrapper { min-height: fit-content; overflow-y: auto; - overflow-x: hidden; 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; +} + #vertical-pinned-tabs-container { padding-inline-end: 0 !important; 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]) { @@ -950,7 +955,7 @@ padding: 0; } -#zen-essentials-container .tabbrowser-tab { +#zen-essentials-container > .tabbrowser-tab { --toolbarbutton-inner-padding: 0; max-width: unset; width: 100% !important; @@ -990,7 +995,7 @@ } @media (-moz-bool-pref: 'zen.theme.essentials-favicon-bg') { - &[visuallyselected] .tab-background { + &[visuallyselected] > .tab-stack > .tab-background { &::after { content: ""; inset: -50%; diff --git a/src/browser/base/content/zen-styles/zen-theme.css b/src/browser/base/content/zen-styles/zen-theme.css index 480f65c52..72955e154 100644 --- a/src/browser/base/content/zen-styles/zen-theme.css +++ b/src/browser/base/content/zen-styles/zen-theme.css @@ -161,11 +161,10 @@ @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)) - ); + --zen-themed-toolbar-bg-transparent: transparent; + @media (-moz-bool-pref: 'zen.widget.windows.acrylic') { + --zen-themed-toolbar-bg-transparent: color-mix(in srgb, var(--zen-themed-toolbar-bg) 85%, transparent 15%); + } } --toolbar-field-background-color: var(--zen-colors-input-bg) !important; diff --git a/src/browser/base/content/zen-styles/zen-workspaces.css b/src/browser/base/content/zen-styles/zen-workspaces.css index 9fbe38108..288032e8b 100644 --- a/src/browser/base/content/zen-styles/zen-workspaces.css +++ b/src/browser/base/content/zen-styles/zen-workspaces.css @@ -456,7 +456,8 @@ position: absolute; max-height: var(--zen-workspace-indicator-height); min-height: var(--zen-workspace-indicator-height); - gap: 5px; + gap: 12px; + white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex-direction: row !important; 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/ZenPinnedTabManager.mjs b/src/browser/base/zen-components/ZenPinnedTabManager.mjs index a3487fee7..97a373cb0 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,13 @@ 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); + } + gBrowser.tabContainer._invalidateCachedTabs(); newTab.initialize(); } @@ -244,43 +249,7 @@ } 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; + gZenUIManager.updateTabsToolbar(); } _onPinnedTabEvent(action, event) { @@ -646,68 +615,70 @@ document.getElementById('context_zen-pinned-tab-separator').hidden = !isVisible; } - moveToAnotherTabContainerIfNecessary(event, draggedTab) { + moveToAnotherTabContainerIfNecessary(event, movingTabs) { const pinnedTabsTarget = 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'); - let moved = false; let isVertical = this.expandedSidebarMode; - let isRegularTabs = false; - // Check for pinned tabs container - if (pinnedTabsTarget) { - if (!draggedTab.pinned) { - gBrowser.pinTab(draggedTab); - moved = true; - } else if (draggedTab.hasAttribute('zen-essential')) { - this.removeEssentials(draggedTab); - gBrowser.pinTab(draggedTab); - moved = true; - } - } - // Check for essentials container - else if (essentialTabsTarget) { - if (!draggedTab.hasAttribute('zen-essential')) { - this.addToEssentials(draggedTab); - moved = true; - isVertical = false; - } - } - // Check for normal tabs container - else if (tabsTarget || event.target.id === 'zen-browser-tabs-wrapper') { - if (draggedTab.pinned && !draggedTab.hasAttribute('zen-essential')) { - gBrowser.unpinTab(draggedTab); - moved = true; - isRegularTabs = true; - } else if (draggedTab.hasAttribute('zen-essential')) { - this.removeEssentials(draggedTab); - moved = true; - isRegularTabs = true; - } - } - - // If the tab was moved, adjust its position relative to the target tab - if (moved) { - const targetTab = event.target.closest('.tabbrowser-tab'); - if (targetTab) { - const rect = targetTab.getBoundingClientRect(); - let newIndex = targetTab._tPos; - - if (isVertical) { - const middleY = targetTab.screenY + rect.height / 2; - if (!isRegularTabs && event.screenY > middleY) { - newIndex++; - } else if (isRegularTabs && event.screenY < middleY) { - newIndex--; - } - } else { - const middleX = targetTab.screenX + rect.width / 2; - if (event.screenX > middleX) { - newIndex++; - } + let moved = false; + for (const draggedTab of movingTabs) { + let isRegularTabs = false; + // Check for pinned tabs container + if (pinnedTabsTarget) { + if (!draggedTab.pinned) { + gBrowser.pinTab(draggedTab); + moved = true; + } else if (draggedTab.hasAttribute('zen-essential')) { + this.removeEssentials(draggedTab); + gBrowser.pinTab(draggedTab); + moved = true; + } + } + // Check for essentials container + else if (essentialTabsTarget) { + if (!draggedTab.hasAttribute('zen-essential')) { + this.addToEssentials(draggedTab); + moved = true; + isVertical = false; + } + } + // Check for normal tabs container + else if (tabsTarget || event.target.id === 'zen-tabs-wrapper') { + if (draggedTab.pinned && !draggedTab.hasAttribute('zen-essential')) { + gBrowser.unpinTab(draggedTab); + moved = true; + isRegularTabs = true; + } else if (draggedTab.hasAttribute('zen-essential')) { + this.removeEssentials(draggedTab); + moved = true; + isRegularTabs = true; + } + } + + // If the tab was moved, adjust its position relative to the target tab + if (moved) { + const targetTab = event.target.closest('.tabbrowser-tab'); + if (targetTab) { + const rect = targetTab.getBoundingClientRect(); + let newIndex = targetTab._tPos; + + if (isVertical) { + const middleY = targetTab.screenY + rect.height / 2; + if (!isRegularTabs && event.screenY > middleY) { + newIndex++; + } else if (isRegularTabs && event.screenY < middleY) { + newIndex--; + } + } else { + const middleX = targetTab.screenX + rect.width / 2; + if (event.screenX > middleX) { + newIndex++; + } + } + gBrowser.moveTabTo(draggedTab, newIndex); } - gBrowser.moveTabTo(draggedTab, newIndex); } } 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 117a3dd15..7baabccac 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,25 @@ 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 +114,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 +138,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,23 +168,34 @@ 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 tabs = gBrowser.tabContainer.allTabs; + const workspaces = await this._workspaces(); + for (const workspace of workspaces.workspaces) { this._createWorkspaceTabsSection(workspace, tabs, perifery); } 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); + // New profile with no workspaces does not have a default selected container + if (defaultSelectedContainer) { + 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; this.registerPinnedResizeObserver(); + this._fixIndicatorsNames(workspaces); } _createWorkspaceSection(workspace) { @@ -200,6 +232,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { _organizeTabsToWorkspaceSections(workspace, section, pinnedSection, tabs) { const workspaceTabs = Array.from(tabs).filter((tab) => tab.getAttribute('zen-workspace-id') === workspace.uuid); for (const tab of workspaceTabs) { + if (tab.hasAttribute('zen-essential')) { + continue; // Ignore essentials as they need to be in their own section + } // remove tab from list tabs.splice(tabs.indexOf(tab), 1); if (tab.pinned) { @@ -208,7 +243,6 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { section.appendChild(tab); } } - this.tabContainer._invalidateCachedTabs(); } initializeWorkspaceNavigation() { @@ -359,7 +393,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) { @@ -509,26 +543,20 @@ 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)); let workspaces = await this._workspaces(); let activeWorkspace = null; if (workspaces.workspaces.length === 0) { activeWorkspace = await this.createAndSaveWorkspace('Default Workspace', true, '🏠'); } else { activeWorkspace = await this.getActiveWorkspace(); - if (!activeWorkspace) { - activeWorkspace = workspaces.workspaces.find((workspace) => workspace.default); - this.activeWorkspace = activeWorkspace?.uuid; - } - if (!activeWorkspace) { - activeWorkspace = workspaces.workspaces[0]; - this.activeWorkspace = activeWorkspace?.uuid; - } + 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); @@ -748,7 +776,11 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { async getActiveWorkspace() { const workspaces = await this._workspaces(); - return workspaces.workspaces.find((workspace) => workspace.uuid === this.activeWorkspace) ?? workspaces.workspaces[0]; + return ( + workspaces.workspaces.find((workspace) => workspace.uuid === this.activeWorkspace) ?? + workspaces.workspaces.find((workspace) => workspace.default) ?? + workspaces.workspaces[0] + ); } // Workspaces dialog UI management @@ -1306,7 +1338,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); } @@ -1331,8 +1363,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() { @@ -1397,8 +1431,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); @@ -1438,11 +1470,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) { @@ -1463,13 +1494,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.setAttribute('hidden', 'true'); + } else { + container.removeAttribute('hidden'); + } } } } @@ -1499,7 +1528,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(); @@ -1512,6 +1541,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { const newTransform = `translateX(${offset}%)`; const isCurrent = offset === 0; if (shouldAnimate) { + element.removeAttribute('hidden'); if (isCurrent) { element.style.opacity = 1; } @@ -1533,15 +1563,14 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } if (offset === 0) { element.setAttribute('active', 'true'); + if (tabToSelect != gBrowser.selectedTab) { + gBrowser.selectedTab = tabToSelect; + } } else { element.removeAttribute('active'); } } await Promise.all(animations); - if (this._beforeSelectedTab) { - this._beforeSelectedTab._visuallySelected = false; - this._beforeSelectedTab = null; - } this._animatingChange = false; } @@ -1588,7 +1617,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) { @@ -1615,22 +1644,23 @@ 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; } + if (tabToSelect) { + tabToSelect._visuallySelected = true; + } + // 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; + } + return tabToSelect; } - async _updateWorkspaceState(window, onInit) { + async _updateWorkspaceState(window, onInit, tabToSelect) { // Update document state document.documentElement.setAttribute('zen-workspace-id', window.uuid); @@ -1639,10 +1669,16 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { // Update workspace UI await this._updateWorkspacesChangeContextMenu(); - document.getElementById('tabbrowser-tabs')._positionPinnedTabs(); gZenUIManager.updateTabsToolbar(); await this._propagateWorkspaceData({ clearCache: false }); + gZenThemePicker.onWorkspaceChange(window); + + document.getElementById('zen-tabs-wrapper').style.scrollbarWidth = 'none'; + await this._animateTabs(window, !onInit && !this._animatingChange, tabToSelect); + await this._organizeWorkspaceStripLocations(window, true); + document.getElementById('zen-tabs-wrapper').style.scrollbarWidth = ''; + // Notify listeners if (this._changeListeners?.length) { for (const listener of this._changeListeners) { @@ -1650,13 +1686,11 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } } - await this._animateTabs(window, !onInit && !this._animatingChange); - // Reset bookmarks this._invalidateBookmarkContainers(); // Update workspace indicator - await this.updateWorkspaceIndicator(); + await this.updateWorkspaceIndicator(window, this.workspaceIndicator); } _invalidateBookmarkContainers() { @@ -1693,7 +1727,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } } - _createWorkspaceData(name, isDefault, icon) { + _createWorkspaceData(name, isDefault, icon, tabs) { let window = { uuid: gZenUIManager.generateUuidv4(), default: isDefault, @@ -1703,9 +1737,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { }; this._prepareNewWorkspace(window); const perifery = document.querySelector('#tabbrowser-arrowscrollbox-periphery[hidden]'); - preifery?.removeAttribute('hidden'); - this._createWorkspaceTabsSection(window, [], perifery); - preifery.setAttribute('hidden', 'true'); + perifery?.removeAttribute('hidden'); + this._createWorkspaceTabsSection(window, tabs, perifery); + perifery.setAttribute('hidden', 'true'); return window; } @@ -1713,15 +1747,37 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { if (!this.workspaceEnabled) { return; } - let workspaceData = this._createWorkspaceData(name, isDefault, icon); + // get extra tabs remaning (e.g. on new profiles) and just move them to the new workspace + const extraTabs = Array.from(gBrowser.tabContainer.arrowScrollbox.children).filter( + (child) => child.tagName === 'tab' && !child.hasAttribute('zen-workspace-id') + ); + let workspaceData = this._createWorkspaceData(name, isDefault, icon, extraTabs); await this.saveWorkspace(workspaceData); - await this.changeWorkspace(workspaceData); this.registerPinnedResizeObserver(); + let changed = extraTabs.length > 0; + if (changed) { + gBrowser.tabContainer._invalidateCachedTabs(); + gBrowser.selectedTab = extraTabs[0]; + } + await this.changeWorkspace(workspaceData); return workspaceData; } + updateTabsContainers() { + this.onPinnedTabsResize([{ target: 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) { + if (!this._hasInitializedTabsStrip) { return; } for (const entry of entries) { @@ -1730,6 +1786,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); } } @@ -1768,19 +1825,28 @@ 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 }); } } } makeSurePinTabIsInCorrectPosition() { + if (!this.pinnedTabsContainer) { + return 0; // until we initialize the pinned tabs container + } 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-glance-tab') === 'true') { + continue; + } if (tab.getAttribute('zen-essential') === 'true') { + const container = document.getElementById('zen-essentials-container'); + container.appendChild(tab); + changed = true; continue; } const workspaceId = tab.getAttribute('zen-workspace-id'); @@ -1796,6 +1862,9 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { if (changed) { gBrowser.tabContainer._invalidateCachedTabs(); } + // Return the number of essentials INSIDE the pinned tabs container so we can correctly change their parent + return Array.from(this.pinnedTabsContainer.children).filter((child) => child.getAttribute('zen-essential') === 'true') + .length; } // Context menu management @@ -2026,4 +2095,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..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 8125c1afc07f3365a2ad030adaf6a560453d7fe6..2856c5f93bfc9d68b98e09b2f26e3d5266c1f46a 100644 +index 908743177d9f95e2e6549c689e7a493ca8668701..2dd53f5fdbffb21dfdc8bf68a6771d4ac0acd8be 100644 --- a/browser/components/sessionstore/SessionStore.sys.mjs +++ b/browser/components/sessionstore/SessionStore.sys.mjs -@@ -3679,6 +3679,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,3 +22,12 @@ index 8125c1afc07f3365a2ad030adaf6a560453d7fe6..2856c5f93bfc9d68b98e09b2f26e3d52 // Restore the state into the new tab. this.restoreTab(newTab, tabState, { restoreImmediately: aRestoreImmediately, +@@ -5315,7 +5317,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 25ae209f8..3a56da16a 100644 --- a/src/browser/components/tabbrowser/content/tabbrowser-js.patch +++ b/src/browser/components/tabbrowser/content/tabbrowser-js.patch @@ -1,18 +1,31 @@ diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js -index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df60a2a6e35 100644 +index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..8f2cd9ecd708e58a6b162740bb21dafeda43b085 100644 --- a/browser/components/tabbrowser/content/tabbrowser.js +++ b/browser/components/tabbrowser/content/tabbrowser.js -@@ -406,11 +406,39 @@ +@@ -406,11 +406,52 @@ return this.tabContainer.visibleTabs; } + get _numVisiblePinTabs() { + let i = 0; + for (let tab of this.tabs) { -+ if (!tab.pinned) { ++ if (!tab.pinned && !tab.hasAttribute("zen-glance-tab")) { + break; + } + if (!tab.hidden) { ++ i += !tab.hasAttribute("zen-glance-tab"); ++ } ++ } ++ return i; ++ } ++ ++ get _numVisiblePinTabsWithoutGlance() { ++ let i = 0; ++ for (let tab of this.tabs) { ++ if (!tab.pinned) { ++ break; ++ } ++ if (!tab.hidden && !tab.hasAttribute("zen-glance-tab")) { + i++; + } + } @@ -22,11 +35,11 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 + get _numZenEssentials() { + let i = 0; + for (let tab of this.tabs) { -+ if (!tab.hasAttribute("zen-essential")) { ++ if (!tab.hasAttribute("zen-essential") && !tab.hasAttribute("zen-glance-tab")) { + break; + } + if (!tab.hidden) { -+ i++; ++ i += !tab.hasAttribute("zen-glance-tab"); + } + } + return i; @@ -37,14 +50,14 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 - if (!this.tabs[i].pinned) { + let i = 0; + for (let tab of this.tabs) { -+ if (!tab.pinned) { ++ if (!tab.pinned && !tab.hasAttribute("zen-glance-tab")) { break; } -+ i++; ++ i += !tab.hasAttribute("zen-glance-tab"); } return i; } -@@ -807,10 +835,10 @@ +@@ -807,7 +848,7 @@ this.showTab(aTab); if (this.tabContainer.verticalMode) { this._handleTabMove(aTab, () => @@ -52,21 +65,17 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 + 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 }); -+ this.moveTabTo(aTab, this._numVisiblePinTabs, { forceStandaloneTab: true }); - } - aTab.setAttribute("pinned", "true"); - this._updateTabBarForPinnedTabs(); -@@ -831,7 +859,7 @@ - this.tabContainer.arrowScrollbox.prepend(aTab); + this.moveTabTo(aTab, this.pinnedTabCount, { forceStandaloneTab: true }); +@@ -828,7 +869,7 @@ + // 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, { -+ this.moveTabTo(aTab, this._numVisiblePinTabs - 1, { - forceStandaloneTab: true, - }); - aTab.removeAttribute("pinned"); -@@ -1055,6 +1083,8 @@ + this.moveTabTo(aTab, this.pinnedTabCount - 1, { +@@ -1055,6 +1096,8 @@ let LOCAL_PROTOCOLS = ["chrome:", "about:", "resource:", "data:"]; @@ -75,7 +84,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 if ( aIconURL && !aLoadingPrincipal && -@@ -1065,6 +1095,9 @@ +@@ -1065,6 +1108,9 @@ ); return; } @@ -85,7 +94,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 let browser = this.getBrowserForTab(aTab); browser.mIconURL = aIconURL; -@@ -1310,6 +1343,7 @@ +@@ -1310,6 +1356,7 @@ if (!this._previewMode) { newTab.recordTimeFromUnloadToReload(); newTab.updateLastAccessed(); @@ -93,7 +102,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 oldTab.updateLastAccessed(); // if this is the foreground window, update the last-seen timestamps. if (this.ownerGlobal == BrowserWindowTracker.getTopWindow()) { -@@ -1462,6 +1496,9 @@ +@@ -1462,6 +1509,9 @@ } let activeEl = document.activeElement; @@ -103,7 +112,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 // If focus is on the old tab, move it to the new tab. if (activeEl == oldTab) { newTab.focus(); -@@ -1785,7 +1822,7 @@ +@@ -1785,7 +1835,7 @@ } _setTabLabel(aTab, aLabel, { beforeTabOpen, isContentTitle, isURL } = {}) { @@ -112,7 +121,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 return false; } -@@ -2387,7 +2424,7 @@ +@@ -2387,7 +2437,7 @@ let panel = this.getPanel(browser); let uniqueId = this._generateUniquePanelID(); @@ -121,16 +130,18 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 aTab.linkedPanel = uniqueId; // Inject the into the DOM if necessary. -@@ -2447,7 +2484,7 @@ +@@ -2446,8 +2496,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; } -@@ -2679,6 +2716,12 @@ +@@ -2679,6 +2729,12 @@ ); } @@ -143,7 +154,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 if (!UserInteraction.running("browser.tabs.opening", window)) { UserInteraction.start("browser.tabs.opening", "initting", window); } -@@ -2742,6 +2785,12 @@ +@@ -2742,6 +2798,12 @@ noInitialLabel, skipBackgroundNotify, }); @@ -156,7 +167,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 if (insertTab) { // insert the tab into the tab container in the correct position this._insertTabAtIndex(t, { -@@ -2885,6 +2934,9 @@ +@@ -2885,6 +2947,9 @@ } } @@ -166,7 +177,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 // Additionally send pinned tab events if (pinned) { this._notifyPinnedStatus(t); -@@ -3403,6 +3455,24 @@ +@@ -3403,6 +3468,21 @@ ) { tabWasReused = true; tab = this.selectedTab; @@ -184,14 +195,11 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 + } + if (tabData.zenPinnedEntry) { + tab.setAttribute("zen-pinned-entry", tabData.zenPinnedEntry); -+ } -+ if (tabData.zenHasStaticLabel) { -+ tab.setAttribute("zen-has-static-label", "true"); + } if (!tabData.pinned) { this.unpinTab(tab); } else { -@@ -3416,6 +3486,7 @@ +@@ -3416,6 +3496,7 @@ restoreTabsLazily && !select && !tabData.pinned; let url = "about:blank"; @@ -199,7 +207,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 if (tabData.entries?.length) { let activeIndex = (tabData.index || tabData.entries.length) - 1; // Ensure the index is in bounds. -@@ -3451,7 +3522,24 @@ +@@ -3451,7 +3532,21 @@ skipLoad: true, preferredRemoteType, }); @@ -218,14 +226,11 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 + } + if (tabData.zenPinnedEntry) { + tab.setAttribute("zen-pinned-entry", tabData.zenPinnedEntry); -+ } -+ if (tabData.zenHasStaticLabel) { -+ tab.setAttribute("zen-has-static-label", "true"); + } if (select) { tabToSelect = tab; } -@@ -3464,8 +3552,8 @@ +@@ -3464,8 +3559,8 @@ // inserted in the DOM. If the tab is not yet in the DOM, // just insert it in the right place from the start. if (!tab.parentNode) { @@ -236,25 +241,16 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 tab.toggleAttribute("pinned", true); this.tabContainer._invalidateCachedTabs(); // Then ensure all the tab open/pinning information is sent. -@@ -3729,7 +3817,7 @@ +@@ -3729,7 +3824,7 @@ // Ensure we have an index if one was not provided. if (typeof index != "number") { // Move the new tab after another tab if needed, to the end otherwise. - index = Infinity; -+ index = Services.prefs.getBoolPref("zen.view.show-newtab-button-top") ? this._numVisiblePinTabs : Infinity; ++ index = Services.prefs.getBoolPref("zen.view.show-newtab-button-top") ? this.pinnedTabCount : Infinity; if ( !bulkOrderedOpen && ((openerTab && -@@ -3773,14 +3861,14 @@ - // Ensure index is within bounds. - if (tab.pinned) { - index = Math.max(index, 0); -- index = Math.min(index, this.pinnedTabCount); -+ index = Math.min(index, this._numVisiblePinTabs); - } else { -- index = Math.max(index, this.pinnedTabCount); -+ index = Math.max(index, this._numVisiblePinTabs); - index = Math.min(index, this.tabs.length); +@@ -3780,7 +3875,7 @@ } /** @type {MozTabbrowserTab|undefined} */ @@ -263,7 +259,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 this.tabContainer._invalidateCachedTabs(); if (tabGroup) { -@@ -4095,6 +4183,9 @@ +@@ -4095,6 +4190,9 @@ return; } @@ -273,7 +269,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 this.removeTabs(selectedTabs); } -@@ -4427,6 +4518,7 @@ +@@ -4427,6 +4525,7 @@ skipSessionStore, } = {} ) { @@ -281,7 +277,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 if (UserInteraction.running("browser.tabs.opening", window)) { UserInteraction.finish("browser.tabs.opening", window); } -@@ -4443,6 +4535,12 @@ +@@ -4443,6 +4542,12 @@ TelemetryStopwatch.start("FX_TAB_CLOSE_TIME_NO_ANIM_MS", aTab); } @@ -294,7 +290,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 // Handle requests for synchronously removing an already // asynchronously closing tab. if (!animate && aTab.closing) { -@@ -4457,7 +4555,9 @@ +@@ -4457,7 +4562,9 @@ // frame created for it (for example, by updating the visually selected // state). let tabWidth = window.windowUtils.getBoundsWithoutFlushing(aTab).width; @@ -305,7 +301,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 if ( !this._beginRemoveTab(aTab, { closeWindowFastpath: true, -@@ -4471,7 +4571,6 @@ +@@ -4471,7 +4578,6 @@ TelemetryStopwatch.cancel("FX_TAB_CLOSE_TIME_NO_ANIM_MS", aTab); return; } @@ -313,7 +309,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 let lockTabSizing = !this.tabContainer.verticalMode && !aTab.pinned && -@@ -4610,14 +4709,14 @@ +@@ -4610,14 +4716,14 @@ !!this.tabsInCollapsedTabGroups.length; if ( aTab.visible && @@ -330,7 +326,16 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 if (closeWindow) { // We've already called beforeunload on all the relevant tabs if we get here, -@@ -5465,10 +5564,10 @@ +@@ -4812,6 +4918,8 @@ + this.tabs[i]._tPos = i; + } + ++ ZenWorkspaces.updateTabsContainers(); ++ + if (!this._windowIsClosing) { + if (wasPinned) { + this.tabContainer._positionPinnedTabs(); +@@ -5465,10 +5573,10 @@ SessionStore.deleteCustomTabValue(aTab, "hiddenBy"); } @@ -343,19 +348,28 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 aTab.selected || aTab.closing || // Tabs that are sharing the screen, microphone or camera cannot be hidden. -@@ -5706,9 +5805,9 @@ +@@ -5706,9 +5814,9 @@ // Don't allow mixing pinned and unpinned tabs. if (aTab.pinned) { - aIndex = Math.min(aIndex, this.pinnedTabCount - 1); -+ aIndex = Math.min(aIndex, this._numVisiblePinTabs - 1); ++ aIndex = Math.min(aIndex, (aTab.hasAttribute('zen-essential') ? this._numZenEssentials : this._numVisiblePinTabsWithoutGlance) - 1); } else { - aIndex = Math.max(aIndex, this.pinnedTabCount); -+ aIndex = Math.max(aIndex, this._numVisiblePinTabs); ++ aIndex = Math.max(aIndex, this._numVisiblePinTabsWithoutGlance); } if (aTab._tPos == aIndex) { return; -@@ -5727,6 +5826,9 @@ +@@ -5717,7 +5825,7 @@ + this._lastRelatedTabMap = new WeakMap(); + + this._handleTabMove(aTab, () => { +- let neighbor = this.tabs[aIndex]; ++ let neighbor = this.tabs.filter(tab => !tab.hasAttribute("zen-glance-tab"))[aIndex]; + if (forceStandaloneTab && neighbor.group) { + neighbor = neighbor.group; + } +@@ -5727,6 +5835,9 @@ this.tabContainer.insertBefore(aTab, neighbor); } }); @@ -365,7 +379,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 } moveTabToGroup(aTab, aGroup) { -@@ -5802,7 +5904,7 @@ +@@ -5802,7 +5913,7 @@ createLazyBrowser, }; @@ -374,7 +388,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 if (aIndex < numPinned || (aTab.pinned && aIndex == numPinned)) { params.pinned = true; } -@@ -7443,6 +7545,7 @@ +@@ -7443,6 +7554,7 @@ aWebProgress.isTopLevel ) { this.mTab.setAttribute("busy", "true"); @@ -382,7 +396,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 gBrowser._tabAttrModified(this.mTab, ["busy"]); this.mTab._notselectedsinceload = !this.mTab.selected; gBrowser.syncThrobberAnimations(this.mTab); -@@ -8411,7 +8514,7 @@ var TabContextMenu = { +@@ -8411,7 +8523,7 @@ var TabContextMenu = { ); contextUnpinSelectedTabs.hidden = !this.contextTab.pinned || !multiselectionContext; @@ -391,7 +405,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 // Move Tab items let contextMoveTabOptions = document.getElementById( "context_moveTabOptions" -@@ -8444,7 +8547,7 @@ var TabContextMenu = { +@@ -8444,7 +8556,7 @@ var TabContextMenu = { let contextMoveTabToStart = document.getElementById("context_moveToStart"); let isFirstTab = tabsToMove[0] == visibleTabs[0] || @@ -400,7 +414,7 @@ index ff90a70bdad6c94ec4b90027ff102972d0eb28e5..efd8feef44ab820666e37cfe5aa75df6 contextMoveTabToStart.disabled = isFirstTab && allSelectedTabsAdjacent; document.getElementById("context_openTabInWindow").disabled = -@@ -8677,6 +8780,7 @@ var TabContextMenu = { +@@ -8677,6 +8789,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 149134733..03326222f 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..393458caa425e0a980223cd3800ea0ef33542c84 100644 --- a/browser/components/tabbrowser/content/tabs.js +++ b/browser/components/tabbrowser/content/tabs.js @@ -94,7 +94,7 @@ @@ -16,7 +16,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 if ( event.button != 0 || - event.target != this.arrowScrollbox || -+ event.target != document.getElementById("zen-browser-tabs-wrapper") || ++ event.target != document.getElementById("zen-tabs-wrapper") || event.composedTarget.localName == "toolbarbutton" ) { return; @@ -52,7 +52,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 this._tabDropIndicator.hidden = true; event.stopPropagation(); + if (draggedTab && dropEffect == "move") { -+ let moved = gZenPinnedTabManager.moveToAnotherTabContainerIfNecessary(event, draggedTab); ++ let moved = gZenPinnedTabManager.moveToAnotherTabContainerIfNecessary(event, movingTabs); + + if (moved) { + this._finishMoveTogetherSelectedTabs(draggedTab); @@ -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. @@ -256,8 +261,8 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 - if (gBrowser.pinnedTabCount !== verticalTabsContainer.children.length) { - let tabs = this.visibleTabs; -+ ZenWorkspaces.makeSurePinTabIsInCorrectPosition(); -+ if (gBrowser.pinnedTabCount !== (verticalTabsContainer.children.length - 1 + document.getElementById("zen-essentials-container").children.length)) { ++ let count = ZenWorkspaces.makeSurePinTabIsInCorrectPosition(); ++ if (gBrowser.pinnedTabCount !== (verticalTabsContainer.children.length - count - 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 = ""; @@ -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,15 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 let absPositionHorizontalTabs = this.overflowing && tabs.length > numPinned && numPinned > 0; -@@ -2074,7 +2098,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; } @@ -297,7 +310,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 let directionX = screenX > dragData.animLastScreenX; let directionY = screenY > dragData.animLastScreenY; -@@ -2257,9 +2281,9 @@ +@@ -2257,9 +2283,9 @@ } let pinned = draggedTab.pinned; @@ -310,7 +323,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 pinned ? numPinned : undefined ); -@@ -2502,8 +2526,9 @@ +@@ -2502,8 +2528,9 @@ ); } @@ -322,7 +335,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 return; } -@@ -2668,9 +2693,9 @@ +@@ -2668,9 +2695,9 @@ function newIndex(aTab, index) { // Don't allow mixing pinned and unpinned tabs. if (aTab.pinned) { @@ -334,7 +347,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 } } -@@ -2754,7 +2779,7 @@ +@@ -2754,7 +2781,7 @@ } _notifyBackgroundTab(aTab) { @@ -343,7 +356,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 return; } -@@ -2772,12 +2797,14 @@ +@@ -2772,12 +2799,14 @@ selectedTab = { left: selectedTab.left, right: selectedTab.right, @@ -359,7 +372,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 selectedTab, ]; }) -@@ -2794,8 +2821,11 @@ +@@ -2794,8 +2823,11 @@ delete this._lastTabToScrollIntoView; // Is the new tab already completely visible? if ( @@ -373,7 +386,7 @@ index 8aeb244ffca9f48661805f5b7d860b5896055562..ab0a6a6ed80608385b4663775b4edf67 ) { return; } -@@ -2803,21 +2833,29 @@ +@@ -2803,21 +2835,29 @@ if (this.arrowScrollbox.smoothScroll) { // Can we make both the new tab and the selected tab completely visible? if ( 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"); 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); + } 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