feat: Make sure to sync tab's permanent key to other windows, b=bug #11750, c=folders, split-view

This commit is contained in:
mr. m
2026-01-01 17:43:57 +01:00
parent 5fb096865c
commit f6ba087539
8 changed files with 56 additions and 19 deletions

View File

@@ -6,7 +6,7 @@
value: true
- name: zen.folders.search.hover-delay
value: 900 # ms
value: 700 # ms
- name: zen.folders.max-subfolders
value: 5

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/sessionstore/SessionStartup.sys.mjs b/browser/components/sessionstore/SessionStartup.sys.mjs
index be23213ae9ec7e59358a17276c6c3764d38d9996..229bb1346f9349892acb1e9e05109b28f5a5b45f 100644
index be23213ae9ec7e59358a17276c6c3764d38d9996..c7bb413d7e2d8ce3f9bc38a925d57e59d882111d 100644
--- a/browser/components/sessionstore/SessionStartup.sys.mjs
+++ b/browser/components/sessionstore/SessionStartup.sys.mjs
@@ -40,6 +40,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
@@ -19,16 +19,17 @@ index be23213ae9ec7e59358a17276c6c3764d38d9996..229bb1346f9349892acb1e9e05109b28
this._initialized = true;
gOnceInitializedDeferred.resolve();
return;
@@ -179,6 +180,8 @@ export var SessionStartup = {
@@ -179,6 +180,9 @@ export var SessionStartup = {
this._initialState = parsed;
}
+ this._initialState ||= {};
+ lazy.ZenSessionStore.onFileRead(this._initialState);
+
if (this._initialState == null) {
// No valid session found.
this._sessionType = this.NO_SESSION;
@@ -335,12 +338,7 @@ export var SessionStartup = {
@@ -335,12 +339,7 @@ export var SessionStartup = {
isAutomaticRestoreEnabled() {
if (this._resumeSessionEnabled === null) {
this._resumeSessionEnabled =

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/tabbrowser/content/drag-and-drop.js b/browser/components/tabbrowser/content/drag-and-drop.js
index 97b931c3c7385a52d20204369fcf6d6999053687..4ac61b298ac64332afb6eac9918fe3eb7ba789ad 100644
index 97b931c3c7385a52d20204369fcf6d6999053687..bd64a97046d2a62e842cc922764ad129da99905f 100644
--- a/browser/components/tabbrowser/content/drag-and-drop.js
+++ b/browser/components/tabbrowser/content/drag-and-drop.js
@@ -32,6 +32,9 @@
@@ -221,7 +221,23 @@ index 97b931c3c7385a52d20204369fcf6d6999053687..4ac61b298ac64332afb6eac9918fe3eb
let isPinned = tab.pinned;
let numPinned = gBrowser.pinnedTabCount;
let allTabs = this._tabbrowserTabs.ariaFocusableItems;
@@ -2457,17 +2489,14 @@
@@ -1598,7 +1630,6 @@
for (let item of this._tabbrowserTabs.ariaFocusableItems) {
item = elementToMove(item);
- item.style.transform = "";
item.removeAttribute("multiselected-move-together");
delete item._moveTogetherSelectedTabsData;
}
@@ -2426,7 +2457,6 @@
for (let item of this._tabbrowserTabs.ariaFocusableItems) {
this._resetGroupTarget(item);
item = elementToMove(item);
- item.style.transform = "";
}
this._tabbrowserTabs.removeAttribute("movingtab-group");
this._tabbrowserTabs.removeAttribute("movingtab-ungroup");
@@ -2457,17 +2487,14 @@
tab.style.left = "";
tab.style.top = "";
tab.style.maxWidth = "";

View File

@@ -80,7 +80,9 @@
init() {
super.init();
this.handle_windowDragEnter = this.handle_windowDragEnter.bind(this);
window.addEventListener('dragleave', this.handle_windowDragLeave.bind(this), true);
window.addEventListener('dragleave', this.handle_windowDragLeave.bind(this), {
capture: true,
});
}
startTabDrag(event, tab, ...args) {
@@ -640,14 +642,14 @@
if (!isTab(draggedTab)) {
return;
}
this.#maybeClearVerticalPinnedGridDragOver(draggedTab);
this.clearSpaceSwitchTimer();
const { clientX, clientY } = event;
const { innerWidth, innerHeight } = window;
const isOutOfWindow =
clientX < 0 || clientX > innerWidth || clientY < 0 || clientY > innerHeight;
if (isOutOfWindow && !this.#isOutOfWindow) {
this.#isOutOfWindow = true;
this.#maybeClearVerticalPinnedGridDragOver(draggedTab);
this.clearSpaceSwitchTimer();
this.clearDragOverVisuals();
const dt = event.dataTransfer;
let dragData = draggedTab._dragData;
@@ -717,6 +719,10 @@
return;
}
this.#isAnimatingTabMove = true;
for (let item of this._tabbrowserTabs.ariaFocusableItems) {
item = elementToMove(item);
item.style.transform = '';
}
const animateElement = (ele, translateY) => {
ele.style.transform = `translateY(${translateY}px)`;
setTimeout(() => {

View File

@@ -686,7 +686,7 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
const position = isRightSide ? 'topleft topright' : 'topright topleft';
return {
position: position,
x: 5,
x: 10,
y: -25,
};
}

View File

@@ -156,24 +156,25 @@ export class nsZenSessionManager {
...this.#sidebar,
spaces: this._migrationData?.spaces || [],
};
// There might be cases where there are no windows in the
// initial state, for example if the user had 'restore previous
// session' disabled before migration. In that case, we try
// to restore the last closed normal window.
if (!initialState.windows?.length) {
let normalClosedWindow = initialState._closedWindows?.find(
(win) => !win.isPopup && !win.isTaskbarTab && !win.isPrivate
);
if (normalClosedWindow) {
initialState.windows = [normalClosedWindow];
initialState.windows = [Cu.cloneInto(normalClosedWindow, {})];
this.log('Restoring tabs from last closed normal window');
}
}
for (const winData of initialState.windows || []) {
winData.spaces = this._migrationData?.spaces || [];
}
return;
}
// If there's no initial state, nothing to restore. This would
// happen if the file is empty or corrupted.
if (!initialState) {
this.log('No initial state to restore!');
// Save the state to the sidebar object so that it gets written
// to the session file.
this.saveState(initialState);
return;
}
// If there are no windows, we create an empty one. By default,

View File

@@ -296,10 +296,12 @@ class nsZenWindowSync {
if (!aTab.id) {
return;
}
let permanentKey = aTab.linkedBrowser.permanentKey;
this.#runOnAllWindows(null, (win) => {
const tab = this.#getItemFromWindow(win, aTab.id);
if (tab) {
tab.permanentKey = aTab.linkedBrowser.permanentKey;
tab.linkedBrowser.permanentKey = permanentKey;
tab.permanentKey = permanentKey;
}
});
}
@@ -578,7 +580,16 @@ class nsZenWindowSync {
() => {
this.log(`Swapping docshells between windows for tab ${aOurTab.id}`);
aOurTab.ownerGlobal.gBrowser.swapBrowsersAndCloseOther(aOurTab, aOtherTab, false);
this.#makeSureTabSyncsPermanentKey(aOurTab);
// Sometimes, when closing a window for example, when we swap the browsers,
// there's a chance that the tab does not have the entries state moved over properly.
// To avoid losing history entries, we have to keep the permanentKey in sync.
this.#makeSureTabSyncsPermanentKey(aOtherTab);
// Since we are moving progress listeners around, there's a chance that we
// trigger a load while making the switch, and since we remove the previous
// tab's listeners, the other browser window will never get the 'finish load' event
// and will stay in a 'busy' state forever.
// To avoid this, we manually check if the other tab is still busy after the swap,
// and if not, we remove the busy attribute from our tab.
if (!aOtherTab.hasAttribute('busy')) {
aOurTab.removeAttribute('busy');
}

View File

@@ -260,6 +260,8 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
return;
}
gBrowser.tabContainer.tabDragAndDrop.finishMoveTogetherSelectedTabs(draggedTab);
} else {
return;
}
if (
!this._lastOpenedTab ||