mirror of
https://github.com/zen-browser/desktop.git
synced 2025-09-05 19:08:18 +00:00
Merge pull request #4282 from zen-browser/new-workspace-functionality
This commit is contained in:
@@ -100,28 +100,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes zen-slide-in {
|
||||
from {
|
||||
transform: translateX(-150%);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes zen-slide-in-reverse {
|
||||
from {
|
||||
transform: translateX(150%);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes zen-deck-fadeIn {
|
||||
0% {
|
||||
transform: scale(0.9);
|
||||
|
@@ -242,23 +242,6 @@
|
||||
& .tabbrowser-tab {
|
||||
transition: scale 0.07s ease;
|
||||
#tabbrowser-tabs &:not([zen-essential='true']) {
|
||||
#tabbrowser-tabs[zen-workspace-animation='previous'] & {
|
||||
animation: zen-slide-in;
|
||||
}
|
||||
|
||||
#tabbrowser-tabs[zen-workspace-animation='next'] & {
|
||||
animation: zen-slide-in-reverse;
|
||||
}
|
||||
|
||||
#tabbrowser-tabs[zen-workspace-animation] & {
|
||||
opacity: 0;
|
||||
transform: translateX(-100%);
|
||||
animation-delay: 0.2s;
|
||||
animation-fill-mode: forwards;
|
||||
animation-duration: 0.2s;
|
||||
animation-timing-function: ease;
|
||||
}
|
||||
|
||||
#tabbrowser-tabs[dont-animate-tabs] & {
|
||||
opacity: 0;
|
||||
}
|
||||
|
@@ -658,7 +658,7 @@
|
||||
setTimeout(() => {
|
||||
// Reactivate the transition after the animation
|
||||
appWrapper.removeAttribute('post-animating');
|
||||
});
|
||||
}, 100);
|
||||
}, 700);
|
||||
});
|
||||
}
|
||||
|
@@ -391,7 +391,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
activeWorkspace = workspaces.workspaces[0];
|
||||
this.activeWorkspace = activeWorkspace?.uuid;
|
||||
}
|
||||
await this.changeWorkspace(activeWorkspace, true);
|
||||
await this.changeWorkspace(activeWorkspace, { onInit: true });
|
||||
}
|
||||
try {
|
||||
if (activeWorkspace) {
|
||||
@@ -415,6 +415,10 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
indicator.addEventListener('click', th);
|
||||
}
|
||||
|
||||
shouldCloseWindow() {
|
||||
return !window.toolbar.visible || Services.prefs.getBoolPref('browser.tabs.closeWindowWithLastTab');
|
||||
}
|
||||
|
||||
handleTabBeforeClose(tab) {
|
||||
if (!this.workspaceEnabled || this.__contextIsDelete) {
|
||||
return null;
|
||||
@@ -425,17 +429,33 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
return null;
|
||||
}
|
||||
|
||||
const shouldOpenNewTabIfLastUnpinnedTabIsClosed = this.shouldOpenNewTabIfLastUnpinnedTabIsClosed;
|
||||
|
||||
let tabs = gBrowser.tabs.filter(
|
||||
(t) =>
|
||||
t.getAttribute('zen-workspace-id') === workspaceID &&
|
||||
(!shouldOpenNewTabIfLastUnpinnedTabIsClosed || !t.pinned || t.getAttribute('pending') !== 'true')
|
||||
);
|
||||
let tabs = gBrowser.visibleTabs;
|
||||
let tabsPinned = tabs.filter((t) => !this.shouldOpenNewTabIfLastUnpinnedTabIsClosed || !t.pinned);
|
||||
|
||||
const shouldCloseWindow = this.shouldCloseWindow();
|
||||
if (tabs.length === 1 && tabs[0] === tab) {
|
||||
let newTab = this._createNewTabForWorkspace({ uuid: workspaceID });
|
||||
return newTab;
|
||||
if (shouldCloseWindow) {
|
||||
// We've already called beforeunload on all the relevant tabs if we get here,
|
||||
// so avoid calling it again:
|
||||
window.skipNextCanClose = true;
|
||||
|
||||
// Closing the tab and replacing it with a blank one is notably slower
|
||||
// than closing the window right away. If the caller opts in, take
|
||||
// the fast path.
|
||||
if (!gBrowser._removingTabs.size) {
|
||||
// This call actually closes the window, unless the user
|
||||
// cancels the operation. We are finished here in both cases.
|
||||
this._isClosingWindow = true;
|
||||
// Inside a setTimeout to avoid reentrancy issues.
|
||||
setTimeout(() => {
|
||||
document.getElementById('cmd_closeWindow').doCommand();
|
||||
}, 100);
|
||||
return this._createNewTabForWorkspace({ uuid: workspaceID });
|
||||
}
|
||||
return null;
|
||||
}
|
||||
} else if (tabsPinned.length === 1 && tabsPinned[0] === tab) {
|
||||
return this._createNewTabForWorkspace({ uuid: workspaceID });
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -1247,7 +1267,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
this._changeListeners.push(func);
|
||||
}
|
||||
|
||||
async changeWorkspace(window, onInit = false) {
|
||||
async changeWorkspace(window, ...args) {
|
||||
if (!this.workspaceEnabled || this._inChangingWorkspace) {
|
||||
return;
|
||||
}
|
||||
@@ -1255,14 +1275,14 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
await SessionStore.promiseInitialized;
|
||||
this._inChangingWorkspace = true;
|
||||
try {
|
||||
await this._performWorkspaceChange(window, onInit);
|
||||
await this._performWorkspaceChange(window, ...args);
|
||||
} finally {
|
||||
this._inChangingWorkspace = false;
|
||||
this.tabContainer.removeAttribute('dont-animate-tabs');
|
||||
}
|
||||
}
|
||||
|
||||
async _performWorkspaceChange(window, onInit) {
|
||||
async _performWorkspaceChange(window, { onInit = false, explicitAnimationDirection = undefined } = {}) {
|
||||
const previousWorkspace = await this.getActiveWorkspace();
|
||||
|
||||
this.activeWorkspace = window.uuid;
|
||||
@@ -1272,6 +1292,21 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
// Refresh tab cache
|
||||
this.tabContainer._invalidateCachedTabs();
|
||||
|
||||
let animationDirection;
|
||||
if (previousWorkspace && !onInit && !this._animatingChange) {
|
||||
animationDirection =
|
||||
explicitAnimationDirection ??
|
||||
(workspaces.workspaces.findIndex((w) => w.uuid === previousWorkspace.uuid) <
|
||||
workspaces.workspaces.findIndex((w) => w.uuid === window.uuid)
|
||||
? 'right'
|
||||
: 'left');
|
||||
}
|
||||
if (animationDirection) {
|
||||
// Animate tabs out of view before changing workspace, therefor we
|
||||
// need to animate in the opposite direction
|
||||
await this._animateTabs(animationDirection === 'left' ? 'right' : 'left', true);
|
||||
}
|
||||
|
||||
// First pass: Handle tab visibility and workspace ID assignment
|
||||
const visibleTabs = this._processTabVisibility(window.uuid, containerId, workspaces);
|
||||
|
||||
@@ -1281,23 +1316,42 @@ 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.tabContainer.removeAttribute('dont-animate-tabs');
|
||||
this._animatingChange = true;
|
||||
setTimeout(() => {
|
||||
this._animatingChange = false;
|
||||
gBrowser.tabContainer.removeAttribute('zen-workspace-animation');
|
||||
}, 600);
|
||||
if (animationDirection) {
|
||||
await this._animateTabs(animationDirection);
|
||||
}
|
||||
}
|
||||
|
||||
async _animateTabs(direction, out = false) {
|
||||
const tabs = gBrowser.visibleTabs.filter((tab) => !tab.hasAttribute('zen-essential'));
|
||||
return new Promise((resolve) => {
|
||||
let count = 0;
|
||||
const onAnimationEnd = () => {
|
||||
count++;
|
||||
if (count >= tabs.length) {
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
this.tabContainer.removeAttribute('dont-animate-tabs');
|
||||
if (out) {
|
||||
for (let tab of tabs) {
|
||||
tab.animate([{ transform: 'translateX(0)' }, { transform: `translateX(${direction === 'left' ? '-' : ''}100%)` }], {
|
||||
duration: 150,
|
||||
easing: 'ease',
|
||||
fill: 'both',
|
||||
}).onfinish = onAnimationEnd;
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (let tab of tabs) {
|
||||
tab.animate([{ transform: `translateX(${direction === 'left' ? '-' : ''}100%)` }, { transform: 'translateX(0)' }], {
|
||||
duration: 150,
|
||||
easing: 'ease',
|
||||
fill: 'both',
|
||||
}).onfinish = onAnimationEnd;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_processTabVisibility(workspaceUuid, containerId, workspaces) {
|
||||
const visibleTabs = new Set();
|
||||
const lastSelectedTab = this._lastSelectedWorkspaceTabs[workspaceUuid];
|
||||
@@ -1524,7 +1578,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
}
|
||||
|
||||
async onLocationChange(browser) {
|
||||
if (!this.workspaceEnabled || this._inChangingWorkspace) {
|
||||
if (!this.workspaceEnabled || this._inChangingWorkspace || this._isClosingWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1663,7 +1717,7 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
||||
}
|
||||
|
||||
let nextWorkspace = workspaces.workspaces[targetIndex];
|
||||
await this.changeWorkspace(nextWorkspace);
|
||||
await this.changeWorkspace(nextWorkspace, { explicitAnimationDirection: offset > 0 ? 'right' : 'left' });
|
||||
}
|
||||
|
||||
_initializeWorkspaceTabContextMenus() {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js
|
||||
index ce68c339f35416574b7bc7ebf8c93378f653242b..46d25e4381eaae71f3aec1025788684c593a60c7 100644
|
||||
index ce68c339f35416574b7bc7ebf8c93378f653242b..07e3f7fcdb3e219c523201929cf07b6878d4d394 100644
|
||||
--- a/browser/components/tabbrowser/content/tabbrowser.js
|
||||
+++ b/browser/components/tabbrowser/content/tabbrowser.js
|
||||
@@ -409,11 +409,39 @@
|
||||
@@ -237,7 +237,7 @@ index ce68c339f35416574b7bc7ebf8c93378f653242b..46d25e4381eaae71f3aec1025788684c
|
||||
if (
|
||||
!this._beginRemoveTab(aTab, {
|
||||
closeWindowFastpath: true,
|
||||
@@ -4556,7 +4657,7 @@
|
||||
@@ -4556,14 +4657,14 @@
|
||||
!!this.tabsInCollapsedTabGroups.length;
|
||||
if (
|
||||
aTab.visible &&
|
||||
@@ -246,6 +246,14 @@ index ce68c339f35416574b7bc7ebf8c93378f653242b..46d25e4381eaae71f3aec1025788684c
|
||||
!anyRemainingTabsInCollapsedTabGroups
|
||||
) {
|
||||
closeWindow =
|
||||
closeWindowWithLastTab != null
|
||||
? closeWindowWithLastTab
|
||||
: !window.toolbar.visible ||
|
||||
- Services.prefs.getBoolPref("browser.tabs.closeWindowWithLastTab");
|
||||
+ Services.prefs.getBoolPref("browser.tabs.closeWindowWithLastTab") && !ZenWorkspaces._isClosingWindow;
|
||||
|
||||
if (closeWindow) {
|
||||
// We've already called beforeunload on all the relevant tabs if we get here,
|
||||
@@ -5411,10 +5512,10 @@
|
||||
SessionStore.deleteCustomTabValue(aTab, "hiddenBy");
|
||||
}
|
||||
|
Reference in New Issue
Block a user