From ec2864902ce7120146b4fa2fdef6f6fea754c09b Mon Sep 17 00:00:00 2001 From: "mr. m" <91018726+mr-cheffy@users.noreply.github.com> Date: Sun, 29 Mar 2026 15:32:27 +0200 Subject: [PATCH] gh-8206: Respect reduce motion more and dont block switch animations (gh-12980) --- src/zen/common/modules/ZenUIManager.mjs | 1 + src/zen/spaces/ZenSpaceCreation.mjs | 70 +++++++++++++------------ src/zen/spaces/ZenSpaceManager.mjs | 24 +++++++-- src/zen/tabs/zen-tabs/vertical-tabs.css | 12 +++-- 4 files changed, 65 insertions(+), 42 deletions(-) diff --git a/src/zen/common/modules/ZenUIManager.mjs b/src/zen/common/modules/ZenUIManager.mjs index c5b64643d..5a3826d2f 100644 --- a/src/zen/common/modules/ZenUIManager.mjs +++ b/src/zen/common/modules/ZenUIManager.mjs @@ -1014,6 +1014,7 @@ window.gZenVerticalTabsManager = { animateItemOpen(aItem) { if ( + gReduceMotion || !gZenUIManager.motion || !aItem || !gZenUIManager._hasLoadedDOM || diff --git a/src/zen/spaces/ZenSpaceCreation.mjs b/src/zen/spaces/ZenSpaceCreation.mjs index 69b8316cf..18243b48d 100644 --- a/src/zen/spaces/ZenSpaceCreation.mjs +++ b/src/zen/spaces/ZenSpaceCreation.mjs @@ -199,25 +199,27 @@ class nsZenWorkspaceCreation extends MozXULElement { this.style.visibility = "visible"; gZenCompactModeManager.getAndApplySidebarWidth(); this.resolveInitialized(); - gZenUIManager.motion - .animate( - this.elementsToAnimate, - { - y: [20, 0], - opacity: [0, 1], - filter: ["blur(2px)", "blur(0)"], - }, - { - duration: 0.6, - type: "spring", - bounce: 0, - delay: gZenUIManager.motion.stagger(0.05, { startDelay: 0.2 }), - } - ) - .then(() => { - this.inputName.focus(); - gZenWorkspaces.workspaceElement(this.workspaceId).hidden = false; - }); + let animation = gZenUIManager.motion.animate( + this.elementsToAnimate, + { + y: [20, 0], + opacity: [0, 1], + filter: ["blur(2px)", "blur(0)"], + }, + { + duration: 0.6, + type: "spring", + bounce: 0, + delay: gZenUIManager.motion.stagger(0.05, { startDelay: 0.2 }), + } + ); + if (gReduceMotion) { + animation.complete(); + } + animation.then(() => { + this.inputName.focus(); + gZenWorkspaces.workspaceElement(this.workspaceId).hidden = false; + }); }); } @@ -303,20 +305,22 @@ class nsZenWorkspaceCreation extends MozXULElement { } async #cleanup() { - await gZenUIManager.motion.animate( - this.elementsToAnimate.reverse(), - { - y: [0, 20], - opacity: [1, 0], - filter: ["blur(0)", "blur(2px)"], - }, - { - duration: 0.4, - type: "spring", - bounce: 0, - delay: gZenUIManager.motion.stagger(0.05), - } - ); + if (!gReduceMotion) { + await gZenUIManager.motion.animate( + this.elementsToAnimate.reverse(), + { + y: [0, 20], + opacity: [1, 0], + filter: ["blur(0)", "blur(2px)"], + }, + { + duration: 0.4, + type: "spring", + bounce: 0, + delay: gZenUIManager.motion.stagger(0.05), + } + ); + } document.getElementById("zen-sidebar-splitter").style.pointerEvents = ""; diff --git a/src/zen/spaces/ZenSpaceManager.mjs b/src/zen/spaces/ZenSpaceManager.mjs index 6b8dd64d1..b58acc44f 100644 --- a/src/zen/spaces/ZenSpaceManager.mjs +++ b/src/zen/spaces/ZenSpaceManager.mjs @@ -44,6 +44,10 @@ class nsZenWorkspaces { _workspaceCache = []; #lastScrollTime = 0; + #currentSpaceSwitchContext = { + promise: null, + animations: [], + }; bookmarkMenus = [ "PlacesToolbar", @@ -1631,9 +1635,18 @@ class nsZenWorkspaces { } async changeWorkspace(workspace, ...args) { - if (!this.workspaceEnabled || this.#inChangingWorkspace) { + if (!this.workspaceEnabled) { return; } + this.#currentSpaceSwitchContext.animations.forEach(animation => { + animation.complete(); + }); + await this.#currentSpaceSwitchContext.promise; + let { resolve, promise } = Promise.withResolvers(); + this.#currentSpaceSwitchContext = { + promise, + animations: [], + }; this.#inChangingWorkspace = true; try { this.log("Changing workspace to", workspace?.uuid); @@ -1642,10 +1655,11 @@ class nsZenWorkspaces { console.error("gZenWorkspaces: Error changing workspace", e); } this.#inChangingWorkspace = false; + resolve(); } _cancelSwipeAnimation() { - this._animateTabs(this.getActiveWorkspaceFromCache(), true); + this.#animateTabs(this.getActiveWorkspaceFromCache(), true); } async #performWorkspaceChange( @@ -1923,7 +1937,7 @@ class nsZenWorkspaces { } /* eslint-disable complexity */ - async _animateTabs( + async #animateTabs( newWorkspace, shouldAnimate, tabToSelect = null, @@ -2253,12 +2267,14 @@ class nsZenWorkspaces { let promiseTimeout = new Promise(resolve => setTimeout(resolve, kGlobalAnimationDuration * 1000 + 50) ); + this.#currentSpaceSwitchContext.animations = animations; // See issue https://github.com/zen-browser/desktop/issues/9334, we need to add // some sort of timeout to the animation promise, just in case it gets stuck. // We are doing a race between the timeout and the animations finishing. await Promise.race([Promise.all(animations), promiseTimeout]).catch( console.error ); + this.#currentSpaceSwitchContext.animations = []; document.documentElement.removeAttribute("animating-background"); if (shouldAnimate) { for (const cloned of clonedEssentials) { @@ -2420,7 +2436,7 @@ class nsZenWorkspaces { gZenUIManager.tabsWrapper.scrollbarWidth = "none"; this.workspaceIcons.activeIndex = workspace.uuid; - await this._animateTabs( + await this.#animateTabs( workspace, !onInit && !this._animatingChange, tabToSelect, diff --git a/src/zen/tabs/zen-tabs/vertical-tabs.css b/src/zen/tabs/zen-tabs/vertical-tabs.css index 027a1997c..6fd06719a 100644 --- a/src/zen/tabs/zen-tabs/vertical-tabs.css +++ b/src/zen/tabs/zen-tabs/vertical-tabs.css @@ -310,11 +310,13 @@ } & .tabbrowser-tab { - &, - & .tab-content > image { - transition: - scale 0.2s ease, - var(--zen-tabbox-element-indent-transition); + @media not (prefers-reduced-motion: reduce) { + &, + & .tab-content > image { + transition: + scale 0.2s ease, + var(--zen-tabbox-element-indent-transition); + } } :root[zen-sidebar-expanded="true"] &:not([zen-glance-tab]) {