mirror of
https://github.com/zen-browser/desktop.git
synced 2026-08-11 17:25:17 +00:00
feat: Improved support for unsynced windows support, b=no-bug, c=workspaces, folders
This commit is contained in:
@@ -66,6 +66,10 @@ zen-panel-ui-gradient-click-to-add = Click to add a color
|
||||
zen-workspace-creation-name =
|
||||
.placeholder = Space Name
|
||||
|
||||
zen-move-tab-to-workspace-button =
|
||||
.label = Move Tabs
|
||||
.tooltiptext = Move all tabs in this window to a Space
|
||||
|
||||
zen-workspaces-panel-context-reorder =
|
||||
.label = Reorder Spaces
|
||||
|
||||
|
||||
@@ -59,3 +59,8 @@
|
||||
<menuseparator />
|
||||
<menuitem id="context_zenOpenSiteSettings" data-l10n-id="zen-site-data-site-settings"/>
|
||||
</menupopup>
|
||||
|
||||
<menupopup id="zenMoveTabsToSyncedWorkspacePopup">
|
||||
# Popup to move tabs to a synced workspace.
|
||||
# This would be automatically populated with the list of available synced workspaces.
|
||||
</menupopup>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/components/sessionstore/SessionStore.sys.mjs b/browser/components/sessionstore/SessionStore.sys.mjs
|
||||
index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..c4a1d14b1eb4e2b26dd903c462fb5cf4d5afeafa 100644
|
||||
index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..ddeb16347bd279934ad3b8fcd158961ff1220f29 100644
|
||||
--- a/browser/components/sessionstore/SessionStore.sys.mjs
|
||||
+++ b/browser/components/sessionstore/SessionStore.sys.mjs
|
||||
@@ -127,6 +127,8 @@ const TAB_EVENTS = [
|
||||
@@ -28,7 +28,18 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..c4a1d14b1eb4e2b26dd903c462fb5cf4
|
||||
this.saveStateDelayed(win);
|
||||
break;
|
||||
case "TabGroupCreate":
|
||||
@@ -2151,7 +2156,6 @@ var SessionStoreInternal = {
|
||||
@@ -2020,6 +2025,10 @@ var SessionStoreInternal = {
|
||||
this._windows[aWindow.__SSi].isTaskbarTab = true;
|
||||
}
|
||||
|
||||
+ if (aWindow.document.documentElement.hasAttribute("zen-unsynced-window")) {
|
||||
+ this._windows[aWindow.__SSi].isZenUnsynced = true;
|
||||
+ }
|
||||
+
|
||||
let tabbrowser = aWindow.gBrowser;
|
||||
|
||||
// add tab change listeners to all already existing tabs
|
||||
@@ -2151,7 +2160,6 @@ var SessionStoreInternal = {
|
||||
if (closedWindowState) {
|
||||
let newWindowState;
|
||||
if (
|
||||
@@ -36,7 +47,7 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..c4a1d14b1eb4e2b26dd903c462fb5cf4
|
||||
!lazy.SessionStartup.willRestore()
|
||||
) {
|
||||
// We want to split the window up into pinned tabs and unpinned tabs.
|
||||
@@ -2215,6 +2219,9 @@ var SessionStoreInternal = {
|
||||
@@ -2215,6 +2223,9 @@ var SessionStoreInternal = {
|
||||
});
|
||||
this._shouldRestoreLastSession = false;
|
||||
}
|
||||
@@ -46,7 +57,7 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..c4a1d14b1eb4e2b26dd903c462fb5cf4
|
||||
|
||||
if (this._restoreLastWindow && aWindow.toolbar.visible) {
|
||||
// always reset (if not a popup window)
|
||||
@@ -2384,11 +2391,9 @@ var SessionStoreInternal = {
|
||||
@@ -2384,11 +2395,9 @@ var SessionStoreInternal = {
|
||||
tabbrowser.selectedTab.label;
|
||||
}
|
||||
|
||||
@@ -58,7 +69,25 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..c4a1d14b1eb4e2b26dd903c462fb5cf4
|
||||
|
||||
// Store the window's close date to figure out when each individual tab
|
||||
// was closed. This timestamp should allow re-arranging data based on how
|
||||
@@ -3373,7 +3378,7 @@ var SessionStoreInternal = {
|
||||
@@ -2465,7 +2474,7 @@ var SessionStoreInternal = {
|
||||
// 2) Flush the window.
|
||||
// 3) When the flush is complete, revisit our decision to store the window
|
||||
// in _closedWindows, and add/remove as necessary.
|
||||
- if (!winData.isPrivate && !winData.isTaskbarTab) {
|
||||
+ if (!winData.isPrivate && !winData.isTaskbarTab && !winData.isZenUnsynced) {
|
||||
this.maybeSaveClosedWindow(winData, isLastWindow);
|
||||
}
|
||||
|
||||
@@ -2486,7 +2495,7 @@ var SessionStoreInternal = {
|
||||
|
||||
// Save non-private windows if they have at
|
||||
// least one saveable tab or are the last window.
|
||||
- if (!winData.isPrivate && !winData.isTaskbarTab) {
|
||||
+ if (!winData.isPrivate && !winData.isTaskbarTab && !winData.isZenUnsynced) {
|
||||
this.maybeSaveClosedWindow(winData, isLastWindow);
|
||||
|
||||
if (!isLastWindow && winData.closedId > -1) {
|
||||
@@ -3373,7 +3382,7 @@ var SessionStoreInternal = {
|
||||
if (!isPrivateWindow && tabState.isPrivate) {
|
||||
return;
|
||||
}
|
||||
@@ -67,7 +96,7 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..c4a1d14b1eb4e2b26dd903c462fb5cf4
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4089,6 +4094,12 @@ var SessionStoreInternal = {
|
||||
@@ -4089,6 +4098,12 @@ var SessionStoreInternal = {
|
||||
Math.min(tabState.index, tabState.entries.length)
|
||||
);
|
||||
tabState.pinned = false;
|
||||
@@ -80,7 +109,7 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..c4a1d14b1eb4e2b26dd903c462fb5cf4
|
||||
|
||||
if (inBackground === false) {
|
||||
aWindow.gBrowser.selectedTab = newTab;
|
||||
@@ -4525,6 +4536,7 @@ var SessionStoreInternal = {
|
||||
@@ -4525,6 +4540,7 @@ var SessionStoreInternal = {
|
||||
// Append the tab if we're opening into a different window,
|
||||
tabIndex: aSource == aTargetWindow ? pos : Infinity,
|
||||
pinned: state.pinned,
|
||||
@@ -88,7 +117,7 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..c4a1d14b1eb4e2b26dd903c462fb5cf4
|
||||
userContextId: state.userContextId,
|
||||
skipLoad: true,
|
||||
preferredRemoteType,
|
||||
@@ -5374,7 +5386,7 @@ var SessionStoreInternal = {
|
||||
@@ -5374,7 +5390,7 @@ var SessionStoreInternal = {
|
||||
|
||||
for (let i = tabbrowser.pinnedTabCount; i < tabbrowser.tabs.length; i++) {
|
||||
let tab = tabbrowser.tabs[i];
|
||||
@@ -97,7 +126,7 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..c4a1d14b1eb4e2b26dd903c462fb5cf4
|
||||
removableTabs.push(tab);
|
||||
}
|
||||
}
|
||||
@@ -5434,7 +5446,7 @@ var SessionStoreInternal = {
|
||||
@@ -5434,7 +5450,7 @@ var SessionStoreInternal = {
|
||||
}
|
||||
|
||||
let workspaceID = aWindow.getWorkspaceID();
|
||||
@@ -106,7 +135,16 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..c4a1d14b1eb4e2b26dd903c462fb5cf4
|
||||
winData.workspaceID = workspaceID;
|
||||
}
|
||||
},
|
||||
@@ -5625,11 +5637,12 @@ var SessionStoreInternal = {
|
||||
@@ -5483,7 +5499,7 @@ var SessionStoreInternal = {
|
||||
|
||||
// collect the data for all windows
|
||||
for (ix in this._windows) {
|
||||
- if (this._windows[ix]._restoring || this._windows[ix].isTaskbarTab) {
|
||||
+ if (this._windows[ix]._restoring || this._windows[ix].isTaskbarTab || this._windows[ix].isZenUnsynced) {
|
||||
// window data is still in _statesToRestore
|
||||
continue;
|
||||
}
|
||||
@@ -5625,11 +5641,12 @@ var SessionStoreInternal = {
|
||||
}
|
||||
|
||||
let tabbrowser = aWindow.gBrowser;
|
||||
@@ -120,7 +158,7 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..c4a1d14b1eb4e2b26dd903c462fb5cf4
|
||||
// update the internal state data for this window
|
||||
for (let tab of tabs) {
|
||||
if (tab == aWindow.FirefoxViewHandler.tab) {
|
||||
@@ -5640,6 +5653,7 @@ var SessionStoreInternal = {
|
||||
@@ -5640,6 +5657,7 @@ var SessionStoreInternal = {
|
||||
tabsData.push(tabData);
|
||||
}
|
||||
|
||||
@@ -128,7 +166,7 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..c4a1d14b1eb4e2b26dd903c462fb5cf4
|
||||
// update tab group state for this window
|
||||
winData.groups = [];
|
||||
for (let tabGroup of aWindow.gBrowser.tabGroups) {
|
||||
@@ -5652,7 +5666,7 @@ var SessionStoreInternal = {
|
||||
@@ -5652,7 +5670,7 @@ var SessionStoreInternal = {
|
||||
// a window is closed, point to the first item in the tab strip instead (it will never be the Firefox View tab,
|
||||
// since it's only inserted into the tab strip after it's selected).
|
||||
if (aWindow.FirefoxViewHandler.tab?.selected) {
|
||||
@@ -137,7 +175,7 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..c4a1d14b1eb4e2b26dd903c462fb5cf4
|
||||
winData.title = tabbrowser.tabs[0].label;
|
||||
}
|
||||
winData.selected = selectedIndex;
|
||||
@@ -5765,8 +5779,8 @@ var SessionStoreInternal = {
|
||||
@@ -5765,8 +5783,8 @@ var SessionStoreInternal = {
|
||||
// selectTab represents.
|
||||
let selectTab = 0;
|
||||
if (overwriteTabs) {
|
||||
@@ -148,7 +186,7 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..c4a1d14b1eb4e2b26dd903c462fb5cf4
|
||||
selectTab = Math.min(selectTab, winData.tabs.length);
|
||||
}
|
||||
|
||||
@@ -5809,6 +5823,8 @@ var SessionStoreInternal = {
|
||||
@@ -5809,6 +5827,8 @@ var SessionStoreInternal = {
|
||||
winData.tabs,
|
||||
winData.groups ?? []
|
||||
);
|
||||
@@ -157,7 +195,7 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..c4a1d14b1eb4e2b26dd903c462fb5cf4
|
||||
this._log.debug(
|
||||
`restoreWindow, createTabsForSessionRestore returned ${tabs.length} tabs`
|
||||
);
|
||||
@@ -6372,6 +6388,25 @@ var SessionStoreInternal = {
|
||||
@@ -6372,6 +6392,25 @@ var SessionStoreInternal = {
|
||||
|
||||
// Most of tabData has been restored, now continue with restoring
|
||||
// attributes that may trigger external events.
|
||||
@@ -183,7 +221,7 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..c4a1d14b1eb4e2b26dd903c462fb5cf4
|
||||
|
||||
if (tabData.pinned) {
|
||||
tabbrowser.pinTab(tab);
|
||||
@@ -7290,7 +7325,7 @@ var SessionStoreInternal = {
|
||||
@@ -7290,7 +7329,7 @@ var SessionStoreInternal = {
|
||||
|
||||
let groupsToSave = new Map();
|
||||
for (let tIndex = 0; tIndex < window.tabs.length; ) {
|
||||
@@ -192,7 +230,7 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..c4a1d14b1eb4e2b26dd903c462fb5cf4
|
||||
// Adjust window.selected
|
||||
if (tIndex + 1 < window.selected) {
|
||||
window.selected -= 1;
|
||||
@@ -7305,7 +7340,7 @@ var SessionStoreInternal = {
|
||||
@@ -7305,7 +7344,7 @@ var SessionStoreInternal = {
|
||||
);
|
||||
// We don't want to increment tIndex here.
|
||||
continue;
|
||||
|
||||
@@ -101,20 +101,7 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
|
||||
.querySelector('menupopup');
|
||||
changeFolderSpace.innerHTML = '';
|
||||
for (const workspace of [...gZenWorkspaces._workspaceCache.workspaces].reverse()) {
|
||||
const item = document.createXULElement('menuitem');
|
||||
item.className = 'zen-workspace-context-menu-item';
|
||||
item.setAttribute('zen-workspace-id', workspace.uuid);
|
||||
item.setAttribute('disabled', workspace.uuid === gZenWorkspaces.activeWorkspace);
|
||||
let name = workspace.name;
|
||||
const iconIsSvg = workspace.icon && workspace.icon.endsWith('.svg');
|
||||
if (workspace.icon && workspace.icon !== '' && !iconIsSvg) {
|
||||
name = `${workspace.icon} ${name}`;
|
||||
}
|
||||
item.setAttribute('label', name);
|
||||
if (iconIsSvg) {
|
||||
item.setAttribute('image', workspace.icon);
|
||||
item.classList.add('zen-workspace-context-icon');
|
||||
}
|
||||
const item = gZenWorkspaces.generateMenuItemForWorkspace(workspace);
|
||||
item.addEventListener('command', (event) => {
|
||||
if (!this.#lastFolderContextMenu) return;
|
||||
this.changeFolderToSpace(
|
||||
|
||||
@@ -428,9 +428,11 @@ class nsZenWindowSync {
|
||||
if (aOurTab.linkedBrowser?.currentURI.spec !== 'about:blank') {
|
||||
aOurTab.linkedBrowser.loadURI(Services.io.newURI('about:blank'), {
|
||||
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
loadFlags: Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY,
|
||||
});
|
||||
}
|
||||
aOurTab.ownerGlobal.gBrowser.swapBrowsersAndCloseOther(aOurTab, aOtherTab, false);
|
||||
aOtherTab.permanentKey = aOurTab.permanentKey;
|
||||
const kAttributesToRemove = ['muted', 'soundplaying', 'sharing', 'pictureinpicture'];
|
||||
// swapBrowsersAndCloseOther already takes care of transferring attributes like 'muted',
|
||||
// but we need to manually remove some attributes from the other tab.
|
||||
@@ -443,10 +445,12 @@ class nsZenWindowSync {
|
||||
aOurTab.linkedBrowser.blur();
|
||||
aOurTab.ownerGlobal.gBrowser._adjustFocusAfterTabSwitch(aOurTab);
|
||||
}
|
||||
for (const tab of [aOurTab, aOtherTab]) {
|
||||
// Ensure the tab's state is flushed after the swap.
|
||||
lazy.TabStateFlusher.flush(tab.linkedBrowser);
|
||||
}
|
||||
// Ensure the tab's state is flushed after the swap. By doing this,
|
||||
// we can re-schedule another session store delayed process to fire.
|
||||
// It's also important to note that if we don't flush the state here,
|
||||
// we would start recieving invalid history changes from the the incorrect
|
||||
// browser view that was just swapped out.
|
||||
lazy.TabStateFlusher.flush(aOurTab.linkedBrowser);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,6 +37,14 @@ class nsZenWorkspace extends MozXULElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static get moveTabToButtonMarkup() {
|
||||
return `
|
||||
<toolbarbutton class="toolbarbutton-1 chromeclass-toolbar-additional zen-workspaces-actions"
|
||||
tooltip="dynamic-shortcut-tooltip"
|
||||
data-l10n-id="zen-move-tab-to-workspace-button" />
|
||||
`;
|
||||
}
|
||||
|
||||
static get inheritedAttributes() {
|
||||
return {
|
||||
'.zen-workspace-tabs-section': 'zen-workspace-id=id',
|
||||
@@ -88,6 +96,20 @@ class nsZenWorkspace extends MozXULElement {
|
||||
gZenWorkspaces.changeWorkspaceIcon();
|
||||
});
|
||||
|
||||
if (!gZenWorkspaces.currentWindowIsSyncing) {
|
||||
let actionsButton = this.indicator.querySelector('.zen-workspaces-actions');
|
||||
const moveTabToFragment = window.MozXULElement.parseXULToFragment(
|
||||
nsZenWorkspace.moveTabToButtonMarkup
|
||||
);
|
||||
actionsButton.after(moveTabToFragment);
|
||||
actionsButton.setAttribute('hidden', 'true');
|
||||
actionsButton = actionsButton.nextElementSibling;
|
||||
actionsButton.addEventListener('command', (event) => {
|
||||
event.stopPropagation();
|
||||
this.#openMoveTabsToWorkspacePanel(event.target);
|
||||
});
|
||||
}
|
||||
|
||||
this.scrollbox._getScrollableElements = () => {
|
||||
const children = [...this.pinnedTabsContainer.children, ...this.tabsContainer.children];
|
||||
if (Services.prefs.getBoolPref('zen.view.show-newtab-button-top', false)) {
|
||||
@@ -209,7 +231,7 @@ class nsZenWorkspace extends MozXULElement {
|
||||
if (newName === '') {
|
||||
return;
|
||||
}
|
||||
let workspaces = (await gZenWorkspaces._workspaces()).workspaces;
|
||||
let workspaces = (await gZenWorkspaces.getWorkspaces()).workspaces;
|
||||
let workspaceData = workspaces.find((workspace) => workspace.uuid === this.workspaceUuid);
|
||||
workspaceData.name = newName;
|
||||
await gZenWorkspaces.saveWorkspace(workspaceData);
|
||||
@@ -256,6 +278,34 @@ class nsZenWorkspace extends MozXULElement {
|
||||
this.style.removeProperty('--toolbox-textcolor');
|
||||
this.style.removeProperty('--zen-primary-color');
|
||||
}
|
||||
|
||||
#openMoveTabsToWorkspacePanel(button) {
|
||||
button = button.closest('toolbarbutton');
|
||||
if (!button) return;
|
||||
|
||||
const popup = document.getElementById('zenMoveTabsToSyncedWorkspacePopup');
|
||||
popup.innerHTML = '';
|
||||
|
||||
gZenWorkspaces.getWorkspaces(true).then((workspaces) => {
|
||||
for (const workspace of workspaces.workspaces) {
|
||||
const item = gZenWorkspaces.generateMenuItemForWorkspace(workspace);
|
||||
item.addEventListener('command', async () => {
|
||||
console.log('TODO: Move tab to workspace', workspace);
|
||||
});
|
||||
popup.appendChild(item);
|
||||
}
|
||||
|
||||
button.setAttribute('open', 'true');
|
||||
popup.addEventListener(
|
||||
'popuphidden',
|
||||
() => {
|
||||
button.removeAttribute('open');
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
popup.openPopup(button, 'after_start', 0, 0, true /* isContextMenu */);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('zen-workspace', nsZenWorkspace);
|
||||
|
||||
@@ -126,7 +126,7 @@ class nsZenWorkspaceIcons extends MozXULElement {
|
||||
}
|
||||
|
||||
async #updateIcons() {
|
||||
const workspaces = await gZenWorkspaces._workspaces();
|
||||
const workspaces = await gZenWorkspaces.getWorkspaces();
|
||||
this.innerHTML = '';
|
||||
for (const workspace of workspaces.workspaces) {
|
||||
const button = this.#createWorkspaceIcon(workspace);
|
||||
|
||||
@@ -129,7 +129,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
this.addPopupListeners();
|
||||
|
||||
await this.#waitForPromises();
|
||||
await this._workspaces();
|
||||
await this.getWorkspaces();
|
||||
|
||||
await this.afterLoadInit();
|
||||
}
|
||||
@@ -319,7 +319,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
}
|
||||
|
||||
async _createDefaultWorkspaceIfNeeded() {
|
||||
const workspaces = await this._workspaces();
|
||||
const workspaces = await this.getWorkspaces();
|
||||
if (!workspaces.workspaces.length) {
|
||||
await this.createAndSaveWorkspace('Space', null, true);
|
||||
this._workspaceCache = null;
|
||||
@@ -414,7 +414,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(async () => {
|
||||
const tabs = gBrowser.tabContainer.allTabs;
|
||||
const workspaces = await this._workspaces();
|
||||
const workspaces = await this.getWorkspaces();
|
||||
for (const workspace of workspaces.workspaces) {
|
||||
await this._createWorkspaceTabsSection(workspace, tabs);
|
||||
}
|
||||
@@ -865,12 +865,12 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
}
|
||||
}
|
||||
|
||||
async _workspaces() {
|
||||
if (this._workspaceCache) {
|
||||
async getWorkspaces(lieToMe = false) {
|
||||
if (this._workspaceCache && !lieToMe) {
|
||||
return this._workspaceCache;
|
||||
}
|
||||
|
||||
if (!this.currentWindowIsSyncing) {
|
||||
if (!this.currentWindowIsSyncing && !lieToMe) {
|
||||
this._workspaceCache = {
|
||||
workspaces: this._tempWorkspace ? [this._tempWorkspace] : [],
|
||||
lastChangeTimestamp: 0,
|
||||
@@ -884,7 +884,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
ZenWorkspacesStorage.getLastChangeTimestamp(),
|
||||
]);
|
||||
|
||||
this._workspaceCache = { workspaces, lastChangeTimestamp };
|
||||
const workspaceCache = { workspaces, lastChangeTimestamp };
|
||||
// Get the active workspace ID from preferences
|
||||
const activeWorkspaceId = this.activeWorkspace;
|
||||
|
||||
@@ -892,18 +892,20 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
const activeWorkspace = this.getWorkspaceFromId(activeWorkspaceId);
|
||||
// Set the active workspace ID to the first one if the one with selected id doesn't exist
|
||||
if (!activeWorkspace) {
|
||||
this.activeWorkspace = this._workspaceCache.workspaces[0]?.uuid;
|
||||
this.activeWorkspace = workspaceCache.workspaces[0]?.uuid;
|
||||
}
|
||||
} else {
|
||||
// Set the active workspace ID to the first one if active workspace doesn't exist
|
||||
this.activeWorkspace = this._workspaceCache.workspaces[0]?.uuid;
|
||||
this.activeWorkspace = workspaceCache.workspaces[0]?.uuid;
|
||||
}
|
||||
// sort by position
|
||||
this._workspaceCache.workspaces.sort(
|
||||
(a, b) => (a.position ?? Infinity) - (b.position ?? Infinity)
|
||||
);
|
||||
workspaceCache.workspaces.sort((a, b) => (a.position ?? Infinity) - (b.position ?? Infinity));
|
||||
|
||||
return this._workspaceCache;
|
||||
if (!lieToMe) {
|
||||
// We don't want our cache to remain for the next calls
|
||||
this._workspaceCache = workspaceCache;
|
||||
}
|
||||
return workspaceCache;
|
||||
}
|
||||
|
||||
async workspaceBookmarks() {
|
||||
@@ -1124,7 +1126,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
|
||||
async #clearAnyZombieTabs() {
|
||||
const tabs = this.allStoredTabs;
|
||||
const workspaces = await this._workspaces();
|
||||
const workspaces = await this.getWorkspaces();
|
||||
for (let tab of tabs) {
|
||||
const workspaceID = tab.getAttribute('zen-workspace-id');
|
||||
if (
|
||||
@@ -1212,6 +1214,24 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
);
|
||||
}
|
||||
|
||||
generateMenuItemForWorkspace(workspace) {
|
||||
const item = document.createXULElement('menuitem');
|
||||
item.className = 'zen-workspace-context-menu-item';
|
||||
item.setAttribute('zen-workspace-id', workspace.uuid);
|
||||
item.setAttribute('disabled', workspace.uuid === this.activeWorkspace);
|
||||
let name = workspace.name;
|
||||
const iconIsSvg = workspace.icon && workspace.icon.endsWith('.svg');
|
||||
if (workspace.icon && workspace.icon !== '' && !iconIsSvg) {
|
||||
name = `${workspace.icon} ${name}`;
|
||||
}
|
||||
item.setAttribute('label', name);
|
||||
if (iconIsSvg) {
|
||||
item.setAttribute('image', workspace.icon);
|
||||
item.classList.add('zen-workspace-context-icon');
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
#contextMenuData = null;
|
||||
updateWorkspaceActionsMenu(event) {
|
||||
if (event.target.id !== 'zenWorkspaceMoreActions') {
|
||||
@@ -1255,20 +1275,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
if (!this.#contextMenuData.workspaceId) {
|
||||
separator.hidden = false;
|
||||
for (const workspace of [...this._workspaceCache.workspaces].reverse()) {
|
||||
const item = document.createXULElement('menuitem');
|
||||
item.className = 'zen-workspace-context-menu-item';
|
||||
item.setAttribute('zen-workspace-id', workspace.uuid);
|
||||
item.setAttribute('disabled', workspace.uuid === this.activeWorkspace);
|
||||
let name = workspace.name;
|
||||
const iconIsSvg = workspace.icon && workspace.icon.endsWith('.svg');
|
||||
if (workspace.icon && workspace.icon !== '' && !iconIsSvg) {
|
||||
name = `${workspace.icon} ${name}`;
|
||||
}
|
||||
item.setAttribute('label', name);
|
||||
if (iconIsSvg) {
|
||||
item.setAttribute('image', workspace.icon);
|
||||
item.classList.add('zen-workspace-context-icon');
|
||||
}
|
||||
const item = this.generateMenuItemForWorkspace(workspace);
|
||||
item.addEventListener('command', (e) => {
|
||||
this.changeWorkspaceWithID(e.target.closest('menuitem').getAttribute('zen-workspace-id'));
|
||||
});
|
||||
@@ -1313,7 +1320,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
}
|
||||
|
||||
async removeWorkspace(windowID) {
|
||||
let workspacesData = await this._workspaces();
|
||||
let workspacesData = await this.getWorkspaces();
|
||||
await this.changeWorkspace(
|
||||
workspacesData.workspaces.find((workspace) => workspace.uuid !== windowID)
|
||||
);
|
||||
@@ -1336,7 +1343,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
}
|
||||
|
||||
async getActiveWorkspace() {
|
||||
const workspaces = await this._workspaces();
|
||||
const workspaces = await this.getWorkspaces();
|
||||
return (
|
||||
workspaces.workspaces.find((workspace) => workspace.uuid === this.activeWorkspace) ??
|
||||
workspaces.workspaces[0]
|
||||
@@ -1370,7 +1377,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
browser.gZenWorkspaces._workspaceCache = null;
|
||||
browser.gZenWorkspaces._workspaceBookmarksCache = null;
|
||||
}
|
||||
let workspaces = await browser.gZenWorkspaces._workspaces();
|
||||
let workspaces = await browser.gZenWorkspaces.getWorkspaces();
|
||||
browser.document
|
||||
.getElementById('cmd_zenCtxDeleteWorkspace')
|
||||
.setAttribute('disabled', workspaces.workspaces.length <= 1);
|
||||
@@ -1423,7 +1430,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
if (this.privateWindowOrDisabled) {
|
||||
return;
|
||||
}
|
||||
const workspaces = (await this._workspaces()).workspaces;
|
||||
const workspaces = (await this.getWorkspaces()).workspaces;
|
||||
const workspace = workspaces.find((w) => w.uuid === id);
|
||||
if (!workspace) {
|
||||
console.warn(`Workspace with ID ${id} not found for reordering.`);
|
||||
@@ -1449,7 +1456,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
}
|
||||
|
||||
async moveWorkspace(draggedWorkspaceId, targetWorkspaceId) {
|
||||
const workspaces = (await this._workspaces()).workspaces;
|
||||
const workspaces = (await this.getWorkspaces()).workspaces;
|
||||
const draggedIndex = workspaces.findIndex((w) => w.uuid === draggedWorkspaceId);
|
||||
const draggedWorkspace = workspaces.splice(draggedIndex, 1)[0];
|
||||
const targetIndex = workspaces.findIndex((w) => w.uuid === targetWorkspaceId);
|
||||
@@ -1662,7 +1669,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
return;
|
||||
}
|
||||
|
||||
const workspaces = await this._workspaces();
|
||||
const workspaces = await this.getWorkspaces();
|
||||
gZenFolders.cancelPopupTimer();
|
||||
|
||||
// Refresh tab cache
|
||||
@@ -1778,7 +1785,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
return;
|
||||
}
|
||||
this._organizingWorkspaceStrip = true;
|
||||
const workspaces = await this._workspaces();
|
||||
const workspaces = await this.getWorkspaces();
|
||||
let workspaceIndex = workspaces.workspaces.findIndex((w) => w.uuid === workspace.uuid);
|
||||
if (!justMove) {
|
||||
this._fixIndicatorsNames(workspaces);
|
||||
@@ -1912,7 +1919,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
const kGlobalAnimationDuration = 0.2;
|
||||
this._animatingChange = true;
|
||||
const animations = [];
|
||||
const workspaces = await this._workspaces();
|
||||
const workspaces = await this.getWorkspaces();
|
||||
const newWorkspaceIndex = workspaces.workspaces.findIndex((w) => w.uuid === newWorkspace.uuid);
|
||||
const isGoingLeft = newWorkspaceIndex <= previousWorkspaceIndex;
|
||||
const clonedEssentials = [];
|
||||
@@ -2215,7 +2222,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
tab,
|
||||
currentWorkspace.uuid,
|
||||
currentWorkspace.containerTabId,
|
||||
await this._workspaces()
|
||||
await this.getWorkspaces()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2274,7 +2281,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
const lastSelectedTab = this._lastSelectedWorkspaceTabs[workspace.uuid];
|
||||
|
||||
const containerId = workspace.containerTabId?.toString();
|
||||
const workspaces = await this._workspaces();
|
||||
const workspaces = await this.getWorkspaces();
|
||||
|
||||
// Save current tab as last selected for old workspace if it shouldn't be visible in new workspace
|
||||
if (oldWorkspaceId && oldWorkspaceId !== workspace.uuid) {
|
||||
@@ -2407,7 +2414,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
|
||||
async _updateWorkspacesChangeContextMenu() {
|
||||
if (gZenWorkspaces.privateWindowOrDisabled) return;
|
||||
const workspaces = await this._workspaces();
|
||||
const workspaces = await this.getWorkspaces();
|
||||
|
||||
const menuPopup = document.getElementById('context-zen-change-workspace-tab-menu-popup');
|
||||
if (!menuPopup) {
|
||||
@@ -2711,7 +2718,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
// Context menu management
|
||||
async contextChangeContainerTab(event) {
|
||||
this._organizingWorkspaceStrip = true;
|
||||
let workspaces = await this._workspaces();
|
||||
let workspaces = await this.getWorkspaces();
|
||||
let workspace = workspaces.workspaces.find(
|
||||
(workspace) => workspace.uuid === (this.#contextMenuData?.workspaceId || this.activeWorkspace)
|
||||
);
|
||||
@@ -2765,7 +2772,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
|
||||
async changeWorkspaceShortcut(offset = 1, whileScrolling = false) {
|
||||
// Cycle through workspaces
|
||||
let workspaces = await this._workspaces();
|
||||
let workspaces = await this.getWorkspaces();
|
||||
let activeWorkspace = await this.getActiveWorkspace();
|
||||
let workspaceIndex = workspaces.workspaces.indexOf(activeWorkspace);
|
||||
|
||||
@@ -2829,7 +2836,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
this._lastSelectedWorkspaceTabs[workspaceID] = gZenGlanceManager.getTabOrGlanceParent(
|
||||
tabs[tabs.length - 1]
|
||||
);
|
||||
const workspaces = await this._workspaces();
|
||||
const workspaces = await this.getWorkspaces();
|
||||
await this.changeWorkspace(
|
||||
workspaces.workspaces.find((workspace) => workspace.uuid === workspaceID)
|
||||
);
|
||||
@@ -2888,7 +2895,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
|
||||
}
|
||||
|
||||
async shortcutSwitchTo(index) {
|
||||
const workspaces = await this._workspaces();
|
||||
const workspaces = await this.getWorkspaces();
|
||||
// The index may be out of bounds, if it doesnt exist, don't do anything
|
||||
if (index >= workspaces.workspaces.length || index < 0) {
|
||||
return;
|
||||
|
||||
@@ -181,13 +181,8 @@
|
||||
height: calc(100% - var(--zen-toolbox-padding) * 2);
|
||||
}
|
||||
|
||||
:root:not([zen-private-window]) & {
|
||||
&:hover,
|
||||
&[open='true'] {
|
||||
&::before {
|
||||
background: var(--tab-hover-background-color);
|
||||
}
|
||||
}
|
||||
:root[zen-private-window] & {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
& .zen-current-workspace-indicator-icon {
|
||||
@@ -228,16 +223,23 @@
|
||||
font-weight: 600;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
|
||||
:root[zen-unsynced-window] & {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.zen-workspaces-actions {
|
||||
margin-left: auto !important;
|
||||
opacity: 0;
|
||||
visibility: collapse;
|
||||
transition: opacity 0.1s;
|
||||
order: 5;
|
||||
--toolbarbutton-inner-padding: 6px !important;
|
||||
|
||||
:root:not([zen-unsynced-window]) & {
|
||||
opacity: 0;
|
||||
visibility: collapse;
|
||||
}
|
||||
|
||||
& image {
|
||||
border-radius: max(calc(var(--border-radius-medium) - 4px), 4px) !important;
|
||||
width: 26px;
|
||||
@@ -248,9 +250,19 @@
|
||||
:root[zen-renaming-tab='true'] & {
|
||||
display: none;
|
||||
}
|
||||
|
||||
:root[zen-unsynced-window] & {
|
||||
.toolbarbutton-text {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.toolbarbutton-icon {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:root:not([zen-private-window]) &:hover .zen-workspaces-actions,
|
||||
:root:not([zen-unsynced-window]) &:hover .zen-workspaces-actions,
|
||||
& .zen-workspaces-actions[open='true'] {
|
||||
visibility: visible;
|
||||
pointer-events: auto;
|
||||
|
||||
Reference in New Issue
Block a user