diff --git a/src/browser/base/content/zen-styles/zen-animations.css b/src/browser/base/content/zen-styles/zen-animations.css index b6fe193f6..f67a1d3a7 100644 --- a/src/browser/base/content/zen-styles/zen-animations.css +++ b/src/browser/base/content/zen-styles/zen-animations.css @@ -56,7 +56,18 @@ @keyframes zen-slide-in { from { - transform: translateX(-30px); + transform: translateX(-100%); + opacity: 0; + } + to { + transform: translateX(0); + opacity: 1; + } +} + +@keyframes zen-slide-in-reverse { + from { + transform: translateX(100%); opacity: 0; } to { @@ -228,9 +239,9 @@ height: 0%; } - 70% { + 80% { /* make the box grow to full width/height */ - opacity: .5; + opacity: 1; transform: translate(-50%, -50%) translateZ(0); top: 50%; left: 50%; @@ -253,31 +264,22 @@ 0% { /* make the box shrink to final width/height and x/y coordinates */ transform: translate(-50%, -50%) translateZ(0); - opacity: 1; width: 85%; height: 100%; top: 50%; left: 50%; - } - - 50% { - /* make the box grow to full width/height */ opacity: 1; - transform: translate(-50%, -50%) translateZ(0); - top: 50%; - left: 50%; - width: 87%; - height: 102%; } 100% { /* make the box appear from initial width/height and x/y coordinates */ + transform: translate(-50%, -50%) translateZ(0); opacity: 0; + width: 47%; + height: 53%; top: 50%; left: 50%; - transform: translate(-50%, -50%) translateZ(0); - width: 0%; - height: 0%; + opacity: 0; } } @@ -293,10 +295,10 @@ to { width: 100%; height: 100%; - top: 0; - left: 0; + top: 50%; + left: 50%; opacity: 1; - transform: none; + transform: translate(-50%, -50%); } } diff --git a/src/browser/base/content/zen-styles/zen-browser-container.css b/src/browser/base/content/zen-styles/zen-browser-container.css index d340d0d3e..65b154417 100644 --- a/src/browser/base/content/zen-styles/zen-browser-container.css +++ b/src/browser/base/content/zen-styles/zen-browser-container.css @@ -4,6 +4,9 @@ border-radius: var(--zen-webview-border-radius, var(--zen-border-radius)); position: relative; + /* For glance */ + transition: transform 0.1s ease-in-out, opacity 0.1s ease-in-out; + box-shadow: 0 0 1px 1px light-dark(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.5)); overflow: hidden; margin: 1px; diff --git a/src/browser/base/content/zen-styles/zen-glance.css b/src/browser/base/content/zen-styles/zen-glance.css index 2ec5956ff..8c09c5095 100644 --- a/src/browser/base/content/zen-styles/zen-glance.css +++ b/src/browser/base/content/zen-styles/zen-glance.css @@ -5,7 +5,6 @@ } .zen-glance-background { - transition: transform 0.1s ease-in-out, opacity 0.1s ease-in-out; transform: scale(0.98); backdrop-filter: blur(5px); opacity: 0.6; @@ -28,7 +27,7 @@ & .browserContainer { opacity: 1; - animation: zen-glance-content-animation-out .5s ease-in-out forwards !important; + animation: zen-glance-content-animation-out .3s ease-in-out forwards !important; & browser { opacity: 1 !important; diff --git a/src/browser/base/content/zen-styles/zen-sidebar-panels.css b/src/browser/base/content/zen-styles/zen-sidebar-panels.css index f67331070..cd44cfbad 100644 --- a/src/browser/base/content/zen-styles/zen-sidebar-panels.css +++ b/src/browser/base/content/zen-styles/zen-sidebar-panels.css @@ -277,7 +277,7 @@ } :root:not([zen-right-side='true']) { - #zen-sidebar-web-panel-wrapper:not(:has(#zen-sidebar-web-panel[pinned='true'])) { + #zen-sidebar-web-panel-wrapper:not(:has(#zen-sidebar-web-panel:is([hidden='true'], [pinned='true']))) { margin-left: 0 !important; margin-right: calc(var(--zen-element-separation) * 2 - 3px) !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 b5018fe3d..41117a5ff 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 @@ -215,7 +215,21 @@ } & .tabbrowser-tab { - animation: zen-slide-in 0.2s ease-in-out; + animation: none; + transition: none; + &[fadein='true']:not([zen-essential='true']) { + #tabbrowser-tabs[zen-workspace-animation='previous'] & { + animation: zen-slide-in-reverse 0.2s ease-in-out; + } + + #tabbrowser-tabs[zen-workspace-animation='next'] & { + animation: zen-slide-in 0.2s ease-in-out; + } + + &[pinned] { + animation-delay: .03s !important; + } + } max-width: unset; padding: 0 !important; diff --git a/src/browser/base/zen-components/ZenWorkspaces.mjs b/src/browser/base/zen-components/ZenWorkspaces.mjs index 15c5272da..16afbf22d 100644 --- a/src/browser/base/zen-components/ZenWorkspaces.mjs +++ b/src/browser/base/zen-components/ZenWorkspaces.mjs @@ -1106,6 +1106,8 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { } async _performWorkspaceChange(window, onInit) { + const previousWorkspace = await this.getActiveWorkspace(); + this.activeWorkspace = window.uuid; const containerId = window.containerTabId?.toString(); const workspaces = await this._workspaces(); @@ -1121,6 +1123,20 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { // Update UI and state await this._updateWorkspaceState(window, onInit); + + // Animate acordingly + if (previousWorkspace && !this._animatingChange) { + // we want to know if we are moving forward or backward in sense of animation + let isNextWorkspace = onInit || + (workspaces.workspaces.findIndex((w) => w.uuid === previousWorkspace.uuid) + < workspaces.workspaces.findIndex((w) => w.uuid === window.uuid)); + gBrowser.tabContainer.setAttribute('zen-workspace-animation', isNextWorkspace ? 'next' : 'previous'); + this._animatingChange = true; + setTimeout(() => { + this._animatingChange = false; + gBrowser.tabContainer.removeAttribute('zen-workspace-animation'); + }, 300); + } } diff --git a/src/browser/components/tabbrowser/content/tabbrowser-js.patch b/src/browser/components/tabbrowser/content/tabbrowser-js.patch index 33fed7d35..699cafcd8 100644 --- a/src/browser/components/tabbrowser/content/tabbrowser-js.patch +++ b/src/browser/components/tabbrowser/content/tabbrowser-js.patch @@ -1,8 +1,8 @@ diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js -index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338e14216df 100644 +index fec3dc8129a4d235fdd05e0390145a02064ebaa5..636b56754f48c1ec931152cf34bab8414a75cebc 100644 --- a/browser/components/tabbrowser/content/tabbrowser.js +++ b/browser/components/tabbrowser/content/tabbrowser.js -@@ -462,11 +462,26 @@ +@@ -402,11 +402,26 @@ return count; }, @@ -31,7 +31,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338 } return i; }, -@@ -860,7 +875,7 @@ +@@ -800,7 +815,7 @@ if (this.tabContainer.verticalMode) { let wasFocused = document.activeElement == this.selectedTab; let oldPosition = aTab._tPos; @@ -40,7 +40,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338 this._updateAfterMoveTabTo(aTab, oldPosition, wasFocused); } else { this.moveTabTo(aTab, this.pinnedTabCount); -@@ -1107,6 +1122,7 @@ +@@ -1047,6 +1062,7 @@ let LOCAL_PROTOCOLS = ["chrome:", "about:", "resource:", "data:"]; @@ -48,7 +48,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338 if ( aIconURL && !aLoadingPrincipal && -@@ -1117,6 +1133,9 @@ +@@ -1057,6 +1073,9 @@ ); return; } @@ -58,7 +58,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338 let browser = this.getBrowserForTab(aTab); browser.mIconURL = aIconURL; -@@ -1346,6 +1365,7 @@ +@@ -1286,6 +1305,7 @@ if (!this._previewMode) { newTab.recordTimeFromUnloadToReload(); newTab.updateLastAccessed(); @@ -66,7 +66,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338 oldTab.updateLastAccessed(); // if this is the foreground window, update the last-seen timestamps. if (this.ownerGlobal == BrowserWindowTracker.getTopWindow()) { -@@ -2431,7 +2451,7 @@ +@@ -2371,7 +2391,7 @@ let panel = this.getPanel(browser); let uniqueId = this._generateUniquePanelID(); @@ -75,7 +75,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338 aTab.linkedPanel = uniqueId; // Inject the into the DOM if necessary. -@@ -2491,7 +2511,7 @@ +@@ -2431,7 +2451,7 @@ // hasSiblings=false on both the existing browser and the new browser. if (this.tabs.length == 2) { this.tabs[0].linkedBrowser.browsingContext.hasSiblings = true; @@ -84,7 +84,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338 } else { aTab.linkedBrowser.browsingContext.hasSiblings = this.tabs.length > 1; } -@@ -2711,6 +2731,11 @@ +@@ -2651,6 +2671,11 @@ ); } @@ -96,7 +96,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338 if (!UserInteraction.running("browser.tabs.opening", window)) { UserInteraction.start("browser.tabs.opening", "initting", window); } -@@ -2780,6 +2805,9 @@ +@@ -2720,6 +2745,9 @@ noInitialLabel, skipBackgroundNotify, }); @@ -106,7 +106,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338 if (insertTab) { // insert the tab into the tab container in the correct position this._insertTabAtIndex(t, { -@@ -3291,6 +3319,23 @@ +@@ -3342,6 +3370,23 @@ ) { tabWasReused = true; tab = this.selectedTab; @@ -130,7 +130,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338 if (!tabData.pinned) { this.unpinTab(tab); } else { -@@ -3304,6 +3349,9 @@ +@@ -3355,6 +3400,9 @@ restoreTabsLazily && !select && !tabData.pinned; let url = "about:blank"; @@ -140,7 +140,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338 if (tabData.entries?.length) { let activeIndex = (tabData.index || tabData.entries.length) - 1; // Ensure the index is in bounds. -@@ -3340,6 +3388,21 @@ +@@ -3391,6 +3439,21 @@ preferredRemoteType, }); @@ -162,7 +162,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338 if (select) { tabToSelect = tab; } -@@ -3374,7 +3437,6 @@ +@@ -3444,7 +3507,6 @@ this.tabContainer._invalidateCachedTabs(); } } @@ -170,7 +170,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338 tab.initialize(); } -@@ -3831,6 +3893,10 @@ +@@ -3992,6 +4054,10 @@ return; } @@ -181,7 +181,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338 this.removeTabs(selectedTabs); }, -@@ -4148,6 +4214,13 @@ +@@ -4309,6 +4375,13 @@ TelemetryStopwatch.start("FX_TAB_CLOSE_TIME_NO_ANIM_MS", aTab); } @@ -195,7 +195,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338 // Handle requests for synchronously removing an already // asynchronously closing tab. if (!animate && aTab.closing) { -@@ -4163,6 +4236,10 @@ +@@ -4324,6 +4397,10 @@ // state). let tabWidth = window.windowUtils.getBoundsWithoutFlushing(aTab).width; @@ -206,7 +206,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338 if ( !this._beginRemoveTab(aTab, { closeWindowFastpath: true, -@@ -4311,7 +4388,7 @@ +@@ -4472,7 +4549,7 @@ var closeWindow = false; var newTab = false; @@ -215,7 +215,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338 closeWindow = closeWindowWithLastTab != null ? closeWindowWithLastTab -@@ -5123,10 +5200,10 @@ +@@ -5265,10 +5342,10 @@ SessionStore.deleteCustomTabValue(aTab, "hiddenBy"); }, @@ -228,7 +228,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338 aTab.selected || aTab.closing || // Tabs that are sharing the screen, microphone or camera cannot be hidden. -@@ -7042,6 +7119,7 @@ +@@ -7181,6 +7258,7 @@ aWebProgress.isTopLevel ) { this.mTab.setAttribute("busy", "true"); @@ -236,7 +236,7 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338 gBrowser._tabAttrModified(this.mTab, ["busy"]); this.mTab._notselectedsinceload = !this.mTab.selected; gBrowser.syncThrobberAnimations(this.mTab); -@@ -7874,7 +7952,7 @@ var TabContextMenu = { +@@ -8114,7 +8192,7 @@ var TabContextMenu = { ); contextUnpinSelectedTabs.hidden = !this.contextTab.pinned || !multiselectionContext; @@ -245,7 +245,16 @@ index 14de79b543cf07b04d06ef5a3f94d9aa988ea39a..439879a6b9c8cc69c569edb6318fe338 // Move Tab items let contextMoveTabOptions = document.getElementById( "context_moveTabOptions" -@@ -8136,6 +8214,7 @@ var TabContextMenu = { +@@ -8148,7 +8226,7 @@ var TabContextMenu = { + let contextMoveTabToStart = document.getElementById("context_moveToStart"); + let isFirstTab = + tabsToMove[0] == visibleTabs[0] || +- tabsToMove[0] == visibleTabs[gBrowser.pinnedTabCount]; ++ tabsToMove[0] == visibleTabs[gBrowser._numVisiblePinTabs]; + contextMoveTabToStart.disabled = isFirstTab && allSelectedTabsAdjacent; + + document.getElementById("context_openTabInWindow").disabled = +@@ -8376,6 +8454,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 7eebd0b7b..a749c8346 100644 --- a/src/browser/components/tabbrowser/content/tabs-js.patch +++ b/src/browser/components/tabbrowser/content/tabs-js.patch @@ -1,7 +1,16 @@ diff --git a/browser/components/tabbrowser/content/tabs.js b/browser/components/tabbrowser/content/tabs.js -index f9e256b143786c18ba85859ca1b11182ab23f1aa..82368b940a6f2c526c471c0e4cc608b836cedbbd 100644 +index f9e256b143786c18ba85859ca1b11182ab23f1aa..f60a8850305f1d7c2eadb6ac6996302f42a08a8a 100644 --- a/browser/components/tabbrowser/content/tabs.js +++ b/browser/components/tabbrowser/content/tabs.js +@@ -541,7 +541,7 @@ + if (this.#isContainerVerticalPinnedExpanded(tab)) { + // In expanded vertical mode, the max number of pinned tabs per row is dynamic + // Set this before adjusting dragged tab's position +- let pinnedTabs = this.visibleTabs.slice(0, gBrowser.pinnedTabCount); ++ let pinnedTabs = this.visibleTabs.slice(0, gBrowser._numVisiblePinTabs); + let tabsPerRow = 0; + let position = 0; + for (let pinnedTab of pinnedTabs) { @@ -918,7 +918,7 @@ let postTransitionCleanup = () => { tab.removeAttribute("tabdrop-samewindow"); @@ -55,6 +64,15 @@ index f9e256b143786c18ba85859ca1b11182ab23f1aa..82368b940a6f2c526c471c0e4cc608b8 selectedTab._notselectedsinceload = false; } +@@ -1571,7 +1574,7 @@ + if (isEndTab && !this._hasTabTempMaxWidth) { + return; + } +- let numPinned = gBrowser.pinnedTabCount; ++ let numPinned = gBrowser._numVisiblePinTabs; + // 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. @@ -1586,7 +1589,7 @@ let tabsToReset = []; for (let i = numPinned; i < tabs.length; i++) { @@ -80,6 +98,33 @@ index f9e256b143786c18ba85859ca1b11182ab23f1aa..82368b940a6f2c526c471c0e4cc608b8 } } +@@ -1681,7 +1684,7 @@ + + _positionPinnedTabs() { + let tabs = this.visibleTabs; +- let numPinned = gBrowser.pinnedTabCount; ++ let numPinned = gBrowser._numVisiblePinTabs; + let absPositionHorizontalTabs = + this.overflowing && tabs.length > numPinned && numPinned > 0; + +@@ -1762,7 +1765,7 @@ + return; + } + +- let tabs = this.visibleTabs.slice(0, gBrowser.pinnedTabCount); ++ let tabs = this.visibleTabs.slice(0, gBrowser._numVisiblePinTabs); + + let directionX = screenX > dragData.animLastScreenX; + let directionY = screenY > dragData.animLastScreenY; +@@ -1948,7 +1951,7 @@ + } + + let pinned = draggedTab.pinned; +- let numPinned = gBrowser.pinnedTabCount; ++ let numPinned = gBrowser._numVisiblePinTabs; + let tabs = this.visibleTabs.slice( + pinned ? 0 : numPinned, + pinned ? numPinned : undefined @@ -2140,8 +2143,8 @@ ); }