mirror of
https://github.com/zen-browser/desktop.git
synced 2026-08-12 17:55:19 +00:00
chore: Finished basic support for split views, b=no-bug, c=folders, split-view
This commit is contained in:
@@ -1131,7 +1131,8 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
|
||||
|
||||
const dropElementGroup = dropElement?.isZenFolder ? dropElement : dropElement?.group;
|
||||
const isSplitGroup = dropElement?.group?.hasAttribute('split-view-group');
|
||||
let firstGroupElem = dropElementGroup.querySelector('.zen-tab-group-start').nextElementSibling;
|
||||
let firstGroupElem =
|
||||
dropElementGroup?.querySelector('.zen-tab-group-start')?.nextElementSibling;
|
||||
if (gBrowser.isTabGroup(firstGroupElem)) firstGroupElem = firstGroupElem.labelElement;
|
||||
|
||||
const isInMiddleZone =
|
||||
|
||||
@@ -247,7 +247,7 @@ export class nsZenSessionManager {
|
||||
*/
|
||||
restoreNewWindow(aWindow, SessionStoreInternal, resolvePromise) {
|
||||
if (aWindow.gZenWorkspaces?.privateWindowOrDisabled) {
|
||||
return;
|
||||
return resolvePromise();
|
||||
}
|
||||
this.log('Restoring new window with Zen session data');
|
||||
const state = lazy.SessionStore.getCurrentState(true);
|
||||
|
||||
@@ -36,8 +36,8 @@ const EVENTS = [
|
||||
'TabGroupRemoved',
|
||||
'TabGroupMoved',
|
||||
|
||||
//'ZenTabRemovedFromSplit',
|
||||
//'ZenSplitViewTabsSplit',
|
||||
'ZenTabRemovedFromSplit',
|
||||
'ZenSplitViewTabsSplit',
|
||||
|
||||
'TabSelect',
|
||||
|
||||
@@ -242,10 +242,14 @@ class nsZenWindowSync {
|
||||
*/
|
||||
#handleNextEvent(aEvent) {
|
||||
const handler = `on_${aEvent.type}`;
|
||||
if (typeof this[handler] === 'function') {
|
||||
return this[handler](aEvent) || Promise.resolve();
|
||||
} else {
|
||||
console.warn(`ZenWindowSync: No handler for event type: ${aEvent.type}`);
|
||||
try {
|
||||
if (typeof this[handler] === 'function') {
|
||||
return this[handler](aEvent) || Promise.resolve();
|
||||
} else {
|
||||
throw new Error(`No handler for event type: ${aEvent.type}`);
|
||||
}
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -483,7 +487,7 @@ class nsZenWindowSync {
|
||||
|
||||
// Restore the listeners for the swapped in tab.
|
||||
if (!onClose) {
|
||||
tabListener = new otherTabBrowser.zenTabProgressListener(aTab, otherBrowser, false, false);
|
||||
tabListener = new otherTabBrowser.zenTabProgressListener(aTab, otherBrowser, true, false);
|
||||
otherTabBrowser._tabListeners.set(aTab, tabListener);
|
||||
|
||||
const notifyAll = Ci.nsIWebProgress.NOTIFY_ALL;
|
||||
@@ -527,10 +531,13 @@ class nsZenWindowSync {
|
||||
this.log(`Swapping docshells between windows for tab ${aOurTab.id}`);
|
||||
aOurTab.ownerGlobal.gBrowser.swapBrowsersAndCloseOther(aOurTab, aOtherTab, false);
|
||||
this.#makeSureTabSyncsPermanentKey(aOurTab);
|
||||
if (!aOtherTab.hasAttribute('busy')) {
|
||||
aOurTab.removeAttribute('busy');
|
||||
}
|
||||
},
|
||||
onClose
|
||||
);
|
||||
const kAttributesToRemove = ['muted', 'soundplaying', 'sharing', 'pictureinpicture'];
|
||||
const kAttributesToRemove = ['muted', 'soundplaying', 'sharing', 'pictureinpicture', 'busy'];
|
||||
// swapBrowsersAndCloseOther already takes care of transferring attributes like 'muted',
|
||||
// but we need to manually remove some attributes from the other tab.
|
||||
for (let attr of kAttributesToRemove) {
|
||||
@@ -676,11 +683,12 @@ class nsZenWindowSync {
|
||||
*
|
||||
* @param {Window} aWindow - The window that triggered the event.
|
||||
* @param {Object} aPreviousTab - The previously selected tab.
|
||||
* @param {boolean} ignoreSameTab - Indicates if the same tab should be ignored.
|
||||
*/
|
||||
async #onTabSwitchOrWindowFocus(aWindow, aPreviousTab = null) {
|
||||
async #onTabSwitchOrWindowFocus(aWindow, aPreviousTab = null, ignoreSameTab = false) {
|
||||
// On some occasions, such as when closing a window, this
|
||||
// function might be called multiple times for the same tab.
|
||||
if (aWindow.gBrowser.selectedTab === this.#lastSelectedTab) {
|
||||
if (aWindow.gBrowser.selectedTab === this.#lastSelectedTab && !ignoreSameTab) {
|
||||
return;
|
||||
}
|
||||
if (aPreviousTab?._zenContentsVisible) {
|
||||
@@ -786,11 +794,13 @@ class nsZenWindowSync {
|
||||
continue;
|
||||
}
|
||||
newTab._zenContentsVisible = true;
|
||||
gBrowser.setTabTitle(newTab);
|
||||
gZenWorkspaces.moveTabToWorkspace(newTab, aWorkspaceId);
|
||||
}
|
||||
}
|
||||
if (success) {
|
||||
aWindow.close();
|
||||
win.gBrowser.selectedTab.linkedBrowser.focus();
|
||||
}
|
||||
};
|
||||
if (!win) {
|
||||
@@ -809,13 +819,11 @@ class nsZenWindowSync {
|
||||
on_TabOpen(aEvent) {
|
||||
const tab = aEvent.target;
|
||||
const window = tab.ownerGlobal;
|
||||
if (tab.selected) {
|
||||
tab._zenContentsVisible = true;
|
||||
}
|
||||
if (tab.id) {
|
||||
// This tab was opened as part of a sync operation.
|
||||
return;
|
||||
}
|
||||
tab._zenContentsVisible = true;
|
||||
tab.id = this.#newTabSyncId;
|
||||
this.#runOnAllWindows(window, (win) => {
|
||||
const newTab = win.gBrowser.addTrustedTab('about:blank', {
|
||||
@@ -1002,12 +1010,16 @@ class nsZenWindowSync {
|
||||
.map((tab) => this.#getItemFromWindow(win, tab.id))
|
||||
.filter(Boolean);
|
||||
if (otherWindowTabs.length > 0 && win.gZenViewSplitter) {
|
||||
const group = win.gZenViewSplitter.splitTabs(otherWindowTabs, 'grid');
|
||||
const group = win.gZenViewSplitter.splitTabs(otherWindowTabs, 'grid', -1);
|
||||
if (group) {
|
||||
group.id = tabGroup.id;
|
||||
let otherTabGroup = group.tabs[0].group;
|
||||
otherTabGroup.id = tabGroup.id;
|
||||
this.#syncItemWithOriginal(aEvent.target, otherTabGroup, win, SYNC_FLAG_MOVE);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return this.#onTabSwitchOrWindowFocus(window, null, /* ignoreSameTab = */ true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1084,8 +1084,12 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
|
||||
*
|
||||
* @param {Tab[]} tabs - The tabs to split.
|
||||
* @param {string|undefined} gridType - The type of grid layout.
|
||||
* @param {number} initialIndex - The index of the initially active tab.
|
||||
* use -1 to avoid selecting any tab.
|
||||
* @return {object|undefined} The split view data or undefined if the split was not performed.
|
||||
*/
|
||||
splitTabs(tabs, gridType, initialIndex = 0) {
|
||||
const tabIndexToUse = Math.max(0, initialIndex);
|
||||
return this.#withoutSplitViewTransition(() => {
|
||||
// TODO: Add support for splitting essential tabs
|
||||
tabs = tabs.filter((t) => !t.hidden && !t.hasAttribute('zen-empty-tab'));
|
||||
@@ -1095,7 +1099,7 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
|
||||
|
||||
const existingSplitTab = tabs.find((tab) => tab.splitView);
|
||||
if (existingSplitTab) {
|
||||
this._moveTabsToContainer(tabs, tabs[initialIndex]);
|
||||
this._moveTabsToContainer(tabs, tabs[tabIndexToUse]);
|
||||
const groupIndex = this._data.findIndex((group) => group.tabs.includes(existingSplitTab));
|
||||
const group = this._data[groupIndex];
|
||||
const gridTypeChange = gridType && group.gridType !== gridType;
|
||||
@@ -1150,8 +1154,8 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
|
||||
layoutTree: this.calculateLayoutTree(tabs, gridType),
|
||||
};
|
||||
this._data.push(splitData);
|
||||
if (!this._sessionRestoring) {
|
||||
window.gBrowser.selectedTab = tabs[initialIndex] ?? tabs[0];
|
||||
if (!this._sessionRestoring && initialIndex >= 0) {
|
||||
window.gBrowser.selectedTab = tabs[tabIndexToUse] ?? tabs[0];
|
||||
}
|
||||
|
||||
// Add tabs to the split view group
|
||||
|
||||
Reference in New Issue
Block a user