feat: Dont mix remoteness when changing browser views and restore window spaces, b=no-bug, c=common, folders, workspaces

This commit is contained in:
mr. m
2025-12-14 00:59:05 +01:00
parent 1207d2163d
commit f094b6239d
7 changed files with 64 additions and 97 deletions

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/sessionstore/SessionStore.sys.mjs b/browser/components/sessionstore/SessionStore.sys.mjs
index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..fb0030061a3bd9df2c8a444970b56ce81600d3af 100644
index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..7674939b31ba0bd444659e0f1e8cc7265c687356 100644
--- a/browser/components/sessionstore/SessionStore.sys.mjs
+++ b/browser/components/sessionstore/SessionStore.sys.mjs
@@ -127,6 +127,8 @@ const TAB_EVENTS = [
@@ -129,7 +129,7 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..fb0030061a3bd9df2c8a444970b56ce8
// window data is still in _statesToRestore
continue;
}
@@ -5625,11 +5649,12 @@ var SessionStoreInternal = {
@@ -5625,11 +5649,15 @@ var SessionStoreInternal = {
}
let tabbrowser = aWindow.gBrowser;
@@ -139,19 +139,14 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..fb0030061a3bd9df2c8a444970b56ce8
let winData = this._windows[aWindow.__SSi];
let tabsData = (winData.tabs = []);
+ winData.activeZenSpace = aWindow.gZenWorkspaces?.activeWorkspace || null;
+ winData.splitViewData = aWindow.gZenViewSplitter?.storeDataForSessionStore();
+ winData.folders = aWindow.gZenFolders?.storeDataForSessionStore() || [];
+
// update the internal state data for this window
for (let tab of tabs) {
if (tab == aWindow.FirefoxViewHandler.tab) {
@@ -5640,6 +5665,7 @@ var SessionStoreInternal = {
tabsData.push(tabData);
}
+ winData.folders = aWindow.gZenFolders?.storeDataForSessionStore() || [];
// update tab group state for this window
winData.groups = [];
for (let tabGroup of aWindow.gBrowser.tabGroups) {
@@ -5652,7 +5678,7 @@ var SessionStoreInternal = {
@@ -5652,7 +5680,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) {
@@ -160,7 +155,7 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..fb0030061a3bd9df2c8a444970b56ce8
winData.title = tabbrowser.tabs[0].label;
}
winData.selected = selectedIndex;
@@ -5765,8 +5791,8 @@ var SessionStoreInternal = {
@@ -5765,8 +5793,8 @@ var SessionStoreInternal = {
// selectTab represents.
let selectTab = 0;
if (overwriteTabs) {
@@ -171,16 +166,17 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..fb0030061a3bd9df2c8a444970b56ce8
selectTab = Math.min(selectTab, winData.tabs.length);
}
@@ -5809,6 +5835,8 @@ var SessionStoreInternal = {
@@ -5809,6 +5837,9 @@ var SessionStoreInternal = {
winData.tabs,
winData.groups ?? []
);
+ aWindow.gZenFolders?.restoreDataFromSessionStore(winData.folders);
+ aWindow.gZenViewSplitter?.restoreDataFromSessionStore(winData.splitViewData);
+ aWindow.gZenWorkspaces?.activeWorkspace = winData.activeZenSpace || null;
this._log.debug(
`restoreWindow, createTabsForSessionRestore returned ${tabs.length} tabs`
);
@@ -6372,6 +6400,25 @@ var SessionStoreInternal = {
@@ -6372,6 +6403,25 @@ var SessionStoreInternal = {
// Most of tabData has been restored, now continue with restoring
// attributes that may trigger external events.
@@ -206,7 +202,7 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..fb0030061a3bd9df2c8a444970b56ce8
if (tabData.pinned) {
tabbrowser.pinTab(tab);
@@ -7290,7 +7337,7 @@ var SessionStoreInternal = {
@@ -7290,7 +7340,7 @@ var SessionStoreInternal = {
let groupsToSave = new Map();
for (let tIndex = 0; tIndex < window.tabs.length; ) {
@@ -215,7 +211,7 @@ index 2c2f43bf743ef458b378e85e9ed44a971711e1d9..fb0030061a3bd9df2c8a444970b56ce8
// Adjust window.selected
if (tIndex + 1 < window.selected) {
window.selected -= 1;
@@ -7305,7 +7352,7 @@ var SessionStoreInternal = {
@@ -7305,7 +7355,7 @@ var SessionStoreInternal = {
);
// We don't want to increment tIndex here.
continue;

View File

@@ -1,44 +0,0 @@
diff --git a/browser/components/urlbar/UrlbarProviderPlaces.sys.mjs b/browser/components/urlbar/UrlbarProviderPlaces.sys.mjs
index 4db61038e5e476bad3a61dbdb707e5222c1f08f8..9eca13d9cfac3b762917aaaa942267effb743cf7 100644
--- a/browser/components/urlbar/UrlbarProviderPlaces.sys.mjs
+++ b/browser/components/urlbar/UrlbarProviderPlaces.sys.mjs
@@ -45,11 +45,13 @@ function defaultQuery(conditions = "") {
let query = `
SELECT h.url, h.title, ${SQL_BOOKMARK_TAGS_FRAGMENT}, h.id, t.open_count,
${lazy.PAGES_FRECENCY_FIELD} AS frecency, t.userContextId,
- h.last_visit_date, NULLIF(t.groupId, '') groupId
+ h.last_visit_date, NULLIF(t.groupId, '') groupId, zp.url AS pinned_url, zp.title AS pinned_title
FROM moz_places h
LEFT JOIN moz_openpages_temp t
ON t.url = h.url
AND (t.userContextId = :userContextId OR (t.userContextId <> -1 AND :userContextId IS NULL))
+ LEFT JOIN zen_pins zp
+ ON zp.url = h.url
WHERE (
(:switchTabsEnabled AND t.open_count > 0) OR
${lazy.PAGES_FRECENCY_FIELD} <> 0
@@ -63,7 +65,7 @@ function defaultQuery(conditions = "") {
:matchBehavior, :searchBehavior, NULL)
ELSE
AUTOCOMPLETE_MATCH(:searchString, h.url,
- h.title, '',
+ IFNULL(zp.title, h.title), '',
h.visit_count, h.typed,
0, t.open_count,
:matchBehavior, :searchBehavior, NULL)
@@ -1176,11 +1178,13 @@ class Search {
? lazy.PlacesUtils.toDate(lastVisitPRTime).getTime()
: undefined;
let tabGroup = row.getResultByName("groupId");
+ let pinnedTitle = row.getResultByIndex(12);
+ let pinnedUrl = row.getResultByIndex("pinned_url");
let match = {
placeId,
- value: url,
- comment: bookmarkTitle || historyTitle,
+ value: pinnedUrl || url,
+ comment: pinnedTitle || bookmarkTitle || historyTitle,
icon: UrlbarUtils.getIconForUrl(url),
frecency: frecency || FRECENCY_DEFAULT,
userContextId,

View File

@@ -38,6 +38,10 @@ export class nsZenMultiWindowFeature {
if (!nsZenMultiWindowFeature.isActiveWindow) {
return;
}
return this.forEachWindow(callback);
}
async forEachWindow(callback) {
for (const browser of nsZenMultiWindowFeature.browsers) {
try {
if (browser.closed) continue;

View File

@@ -405,7 +405,7 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
if (selectedTab) {
selectedTab.setAttribute('zen-workspace-id', newWorkspace.uuid);
selectedTab.removeAttribute('folder-active');
gZenWorkspaces._lastSelectedWorkspaceTabs[newWorkspace.uuid] = selectedTab;
gZenWorkspaces.lastSelectedWorkspaceTabs[newWorkspace.uuid] = selectedTab;
}
resolve();
});
@@ -421,10 +421,10 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
tab.style.height = '';
}
gBrowser.TabStateFlusher.flush(tab.linkedBrowser);
if (gZenWorkspaces._lastSelectedWorkspaceTabs[currentWorkspace.uuid] === tab) {
if (gZenWorkspaces.lastSelectedWorkspaceTabs[currentWorkspace.uuid] === tab) {
// This tab is no longer the last selected tab in the previous workspace because it's being moved to
// the current workspace
delete gZenWorkspaces._lastSelectedWorkspaceTabs[currentWorkspace.uuid];
delete gZenWorkspaces.lastSelectedWorkspaceTabs[currentWorkspace.uuid];
}
}
}
@@ -443,9 +443,9 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
// we may encounter
tab.group.setAttribute('zen-workspace-id', workspaceId);
gBrowser.TabStateFlusher.flush(tab.linkedBrowser);
if (gZenWorkspaces._lastSelectedWorkspaceTabs[workspaceId] === tab) {
if (gZenWorkspaces.lastSelectedWorkspaceTabs[workspaceId] === tab) {
// This tab is no longer the last selected tab in the previous workspace because it's being moved to a new workspace
delete gZenWorkspaces._lastSelectedWorkspaceTabs[workspaceId];
delete gZenWorkspaces.lastSelectedWorkspaceTabs[workspaceId];
}
}
folder.dispatchEvent(new CustomEvent('ZenFolderChangedWorkspace', { bubbles: true }));

View File

@@ -396,6 +396,9 @@ class nsZenWindowSync {
* @param {MozTabbrowserTab|MozTabbrowserTabGroup} aOriginalItem - The original item to match.
* @param {MozTabbrowserTab|MozTabbrowserTabGroup} aTargetItem - The target item to move.
* @param {Window} aWindow - The window containing the items.
* @param {Object} options - Additional options for moving the item.
* @param {boolean} options.isEssential - Indicates if the item is essential.
* @param {boolean} options.isPinned - Indicates if the item is pinned.
*/
#moveItemToMatchOriginal(aOriginalItem, aTargetItem, aWindow, { isEssential, isPinned }) {
const { gBrowser, gZenWorkspaces } = aWindow;
@@ -425,7 +428,9 @@ class nsZenWindowSync {
if (isEssential) {
container = gZenWorkspaces.getEssentialsSection(aTargetItem);
} else {
const workspaceId = aTargetItem.getAttribute('zen-workspace-id');
const workspaceId =
aTargetItem.getAttribute('zen-workspace-id') ||
aOriginalItem.ownerGlobal.gZenWorkspaces.activeWorkspace;
const workspaceElement = gZenWorkspaces.workspaceElement(workspaceId);
container = isPinned
? workspaceElement?.pinnedTabsContainer
@@ -515,6 +520,10 @@ class nsZenWindowSync {
* @param {boolean} onClose - Indicates if the swap is done during a tab close operation.
*/
#swapBrowserDocSheellsInner(aOurTab, aOtherTab, focus = true, onClose = false) {
// Can't swap between chrome and content processes.
if (aOurTab.linkedBrowser.isRemoteBrowser != aOtherTab.linkedBrowser.isRemoteBrowser) {
return false;
}
// Load about:blank if by any chance we loaded the previous tab's URL.
// TODO: We should maybe start using a singular about:blank preloaded view
// to avoid loading a full blank page each time and wasting resources.
@@ -558,6 +567,7 @@ class nsZenWindowSync {
// we would start receiving invalid history changes from the the incorrect
// browser view that was just swapped out.
lazy.TabStateFlusher.flush(aOurTab.linkedBrowser);
return true;
}
/**

View File

@@ -1318,7 +1318,7 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
// Use theme from workspace object or passed theme
let workspaceTheme = theme || workspace.theme;
await this.foreachWindowAsActive(async (browser) => {
await this.forEachWindow(async (browser) => {
if (!browser.gZenThemePicker?.promiseInitialized) {
return;
}

View File

@@ -9,11 +9,12 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
/**
* Stores workspace IDs and their last selected tabs.
*/
_lastSelectedWorkspaceTabs = {};
_inChangingWorkspace = false;
lastSelectedWorkspaceTabs = {};
#inChangingWorkspace = false;
draggedElement = null;
#canDebug = Services.prefs.getBoolPref('zen.workspaces.debug', false);
#activeWorkspace = '';
_swipeState = {
isGestureActive: true,
@@ -21,7 +22,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
direction: null,
};
_lastScrollTime = 0;
#lastScrollTime = 0;
bookmarkMenus = [
'PlacesToolbar',
@@ -116,7 +117,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
ChromeUtils.defineLazyGetter(this, 'workspaceIcons', () =>
document.getElementById('zen-workspaces-button')
);
this._activeWorkspace = Services.prefs.getStringPref('zen.workspaces.active', '');
this.#activeWorkspace ||= Services.prefs.getStringPref('zen.workspaces.active', '');
if (this.isPrivateWindow) {
document.documentElement.setAttribute('zen-private-window', 'true');
@@ -325,7 +326,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
}
}
_initializeEmptyTab() {
#initializeEmptyTab() {
for (const tab of gBrowser.tabs) {
// Check if session store has an empty tab
if (tab.hasAttribute('zen-empty-tab') && !tab.pinned) {
@@ -405,7 +406,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
return document.getElementById(workspaceId);
}
async initializeTabsStripSections() {
async #initializeTabsStripSections() {
await SessionStore.promiseInitialized;
await SessionStore.promiseAllWindowsRestored;
const perifery = document.getElementById('tabbrowser-arrowscrollbox-periphery');
@@ -611,7 +612,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
toolbox.addEventListener(
'wheel',
async (event) => {
(event) => {
if (this.privateWindowOrDisabled) return;
// Only process non-gesture scrolls
@@ -637,7 +638,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
}
const currentTime = Date.now();
if (currentTime - this._lastScrollTime < scrollCooldown) return;
if (currentTime - this.#lastScrollTime < scrollCooldown) return;
//this decides which delta to use
const delta = isVerticalScroll ? event.deltaY : event.deltaX;
@@ -649,7 +650,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
let direction = this.naturalScroll ? -1 : 1;
this.changeWorkspaceShortcut(rawDirection * direction);
this._lastScrollTime = currentTime;
this.#lastScrollTime = currentTime;
},
{ passive: true }
);
@@ -704,7 +705,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
}
_handleSwipeMayStart(event) {
if (this.privateWindowOrDisabled || this._inChangingWorkspace) return;
if (this.privateWindowOrDisabled || this.#inChangingWorkspace) return;
if (
event.target.closest('#zen-sidebar-foot-buttons') ||
event.target.closest('#urlbar[zen-floating-urlbar="true"]')
@@ -789,11 +790,11 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
}
get activeWorkspace() {
return this._activeWorkspace;
return this.#activeWorkspace;
}
set activeWorkspace(value) {
this._activeWorkspace = value;
this.#activeWorkspace = value;
if (this.privateWindowOrDisabled) {
return;
}
@@ -881,7 +882,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
workspaces: this._tempWorkspace ? [this._tempWorkspace] : [],
lastChangeTimestamp: 0,
};
this._activeWorkspace = this._tempWorkspace?.uuid;
this.#activeWorkspace = this._tempWorkspace?.uuid;
return this._workspaceCache;
}
@@ -950,8 +951,8 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
console.error('gZenWorkspaces: Error initializing theme picker', e);
}
await this.workspaceBookmarks();
await this.initializeTabsStripSections();
this._initializeEmptyTab();
await this.#initializeTabsStripSections();
this.#initializeEmptyTab();
await this.changeWorkspace(activeWorkspace, { onInit: true });
this.#fixTabPositions();
this.onWindowResize();
@@ -1332,7 +1333,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
workspacesData.workspaces.find((workspace) => workspace.uuid !== windowID)
);
await this.#deleteAllTabsInWorkspace(windowID);
delete this._lastSelectedWorkspaceTabs[windowID];
delete this.lastSelectedWorkspaceTabs[windowID];
await ZenWorkspacesStorage.removeWorkspace(windowID);
// Remove the workspace from the cache
this._workspaceCache.workspaces = this._workspaceCache.workspaces.filter(
@@ -1645,19 +1646,19 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
async changeWorkspace(workspace, ...args) {
if (
!this.workspaceEnabled ||
this._inChangingWorkspace ||
this.#inChangingWorkspace ||
gNavToolbox.hasAttribute('movingtab')
) {
return;
}
this._inChangingWorkspace = true;
this.#inChangingWorkspace = true;
try {
this.log('Changing workspace to', workspace?.uuid);
await this._performWorkspaceChange(workspace, ...args);
} catch (e) {
console.error('gZenWorkspaces: Error changing workspace', e);
}
this._inChangingWorkspace = false;
this.#inChangingWorkspace = false;
}
_cancelSwipeAnimation() {
@@ -1762,7 +1763,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
) {
if (
workspaceElement &&
!(this._inChangingWorkspace && !forAnimation && !this._alwaysAnimatePaddingTop)
!(this.#inChangingWorkspace && !forAnimation && !this._alwaysAnimatePaddingTop)
) {
delete this._alwaysAnimatePaddingTop;
const essentialsHeight = essentialContainer.getBoundingClientRect().height;
@@ -1875,7 +1876,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
const grainValue =
minGrain +
(maxGrain - minGrain) * (existingGrain > nextGrain ? 1 - percentage : percentage);
if (!this._inChangingWorkspace) {
if (!this.#inChangingWorkspace) {
gZenThemePicker.updateNoise(grainValue);
}
}
@@ -2285,14 +2286,14 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
async _handleTabSelection(workspace, onInit, previousWorkspaceId) {
const currentSelectedTab = gBrowser.selectedTab;
const oldWorkspaceId = previousWorkspaceId;
const lastSelectedTab = this._lastSelectedWorkspaceTabs[workspace.uuid];
const lastSelectedTab = this.lastSelectedWorkspaceTabs[workspace.uuid];
const containerId = workspace.containerTabId?.toString();
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) {
this._lastSelectedWorkspaceTabs[oldWorkspaceId] =
this.lastSelectedWorkspaceTabs[oldWorkspaceId] =
gZenGlanceManager.getTabOrGlanceParent(currentSelectedTab);
}
@@ -2652,7 +2653,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
if (workspaceID) {
if (tab.hasAttribute('change-workspace') && this.moveTabToWorkspace(tab, workspaceID)) {
this._lastSelectedWorkspaceTabs[workspaceID] = gZenGlanceManager.getTabOrGlanceParent(tab);
this.lastSelectedWorkspaceTabs[workspaceID] = gZenGlanceManager.getTabOrGlanceParent(tab);
tab.removeAttribute('change-workspace');
const workspace = this.getWorkspaceFromId(workspaceID);
setTimeout(() => {
@@ -2684,7 +2685,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
async onLocationChange(event) {
let tab = event.target;
this.#changeToEmptyTab();
if (!this.workspaceEnabled || this._inChangingWorkspace || this._isClosingWindow) {
if (!this.workspaceEnabled || this.#inChangingWorkspace || this._isClosingWindow) {
return;
}
@@ -2708,7 +2709,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
// Only update last selected tab for non-essential tabs in their workspace
if (workspaceID === activeWorkspace.uuid) {
this._lastSelectedWorkspaceTabs[workspaceID] = gZenGlanceManager.getTabOrGlanceParent(tab);
this.lastSelectedWorkspaceTabs[workspaceID] = gZenGlanceManager.getTabOrGlanceParent(tab);
}
// Switch workspace if needed
@@ -2833,14 +2834,14 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
const previousWorkspaceID = document.documentElement.getAttribute('zen-workspace-id');
for (let tab of tabs) {
this.moveTabToWorkspace(tab, workspaceID);
if (this._lastSelectedWorkspaceTabs[previousWorkspaceID] === tab) {
if (this.lastSelectedWorkspaceTabs[previousWorkspaceID] === tab) {
// This tab is no longer the last selected tab in the previous workspace because it's being moved to
// the current workspace
delete this._lastSelectedWorkspaceTabs[previousWorkspaceID];
delete this.lastSelectedWorkspaceTabs[previousWorkspaceID];
}
}
// Make sure we select the last tab in the new workspace
this._lastSelectedWorkspaceTabs[workspaceID] = gZenGlanceManager.getTabOrGlanceParent(
this.lastSelectedWorkspaceTabs[workspaceID] = gZenGlanceManager.getTabOrGlanceParent(
tabs[tabs.length - 1]
);
const workspaces = await this.getWorkspaces();
@@ -3109,7 +3110,7 @@ class nsZenWorkspaces extends nsZenMultiWindowFeature {
this._workspaceChangeInProgress = true;
try {
this._lastSelectedWorkspaceTabs[workspaceToSwitch.uuid] =
this.lastSelectedWorkspaceTabs[workspaceToSwitch.uuid] =
gZenGlanceManager.getTabOrGlanceParent(tab);
await this.changeWorkspace(workspaceToSwitch);
} finally {