diff --git a/prefs/zen/folders.yaml b/prefs/zen/folders.yaml index 7a8edc5ca..2e80ea0cb 100644 --- a/prefs/zen/folders.yaml +++ b/prefs/zen/folders.yaml @@ -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 diff --git a/src/browser/components/sessionstore/SessionStartup-sys-mjs.patch b/src/browser/components/sessionstore/SessionStartup-sys-mjs.patch index 4425f4e0e..ae491f2ca 100644 --- a/src/browser/components/sessionstore/SessionStartup-sys-mjs.patch +++ b/src/browser/components/sessionstore/SessionStartup-sys-mjs.patch @@ -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 = diff --git a/src/browser/components/tabbrowser/content/drag-and-drop-js.patch b/src/browser/components/tabbrowser/content/drag-and-drop-js.patch index a6e62dcab..6b34e716e 100644 --- a/src/browser/components/tabbrowser/content/drag-and-drop-js.patch +++ b/src/browser/components/tabbrowser/content/drag-and-drop-js.patch @@ -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 = ""; diff --git a/src/zen/drag-and-drop/ZenDragAndDrop.js b/src/zen/drag-and-drop/ZenDragAndDrop.js index fa51f63ca..01dacf8b5 100644 --- a/src/zen/drag-and-drop/ZenDragAndDrop.js +++ b/src/zen/drag-and-drop/ZenDragAndDrop.js @@ -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(() => { diff --git a/src/zen/folders/ZenFolders.mjs b/src/zen/folders/ZenFolders.mjs index a8ff7497b..43962c99f 100644 --- a/src/zen/folders/ZenFolders.mjs +++ b/src/zen/folders/ZenFolders.mjs @@ -686,7 +686,7 @@ class nsZenFolders extends nsZenDOMOperatedFeature { const position = isRightSide ? 'topleft topright' : 'topright topleft'; return { position: position, - x: 5, + x: 10, y: -25, }; } diff --git a/src/zen/sessionstore/ZenSessionManager.sys.mjs b/src/zen/sessionstore/ZenSessionManager.sys.mjs index 2a30e2ce1..6c6155712 100644 --- a/src/zen/sessionstore/ZenSessionManager.sys.mjs +++ b/src/zen/sessionstore/ZenSessionManager.sys.mjs @@ -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, diff --git a/src/zen/sessionstore/ZenWindowSync.sys.mjs b/src/zen/sessionstore/ZenWindowSync.sys.mjs index 6ab4dd5e2..2f73b7064 100644 --- a/src/zen/sessionstore/ZenWindowSync.sys.mjs +++ b/src/zen/sessionstore/ZenWindowSync.sys.mjs @@ -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'); } diff --git a/src/zen/split-view/ZenViewSplitter.mjs b/src/zen/split-view/ZenViewSplitter.mjs index c9e99b861..28e3c9cf2 100644 --- a/src/zen/split-view/ZenViewSplitter.mjs +++ b/src/zen/split-view/ZenViewSplitter.mjs @@ -260,6 +260,8 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature { return; } gBrowser.tabContainer.tabDragAndDrop.finishMoveTogetherSelectedTabs(draggedTab); + } else { + return; } if ( !this._lastOpenedTab ||