Theseus: a tab can go back into another window
A tab moved to its own window had no way back. Dragging a tab onto another window's tab bar now moves it there, page and all, and the right-click menu lists the other windows under Move to window. A window whose last tab leaves closes.
This commit is contained in:
parent
852d198eef
commit
3861925811
1 changed files with 47 additions and 0 deletions
47
main.js
47
main.js
|
|
@ -5179,6 +5179,37 @@ function moveTabToNewWindow(id, at) {
|
|||
}));
|
||||
return true;
|
||||
}
|
||||
// Moves a tab into an existing window (dest), page and all, at the end of
|
||||
// its tab bar, and brings that window forward. A window left without tabs
|
||||
// closes, like one whose last tab was closed.
|
||||
function moveTabToWindow(id, dest) {
|
||||
const t = tabById(id);
|
||||
if (!t || !t.w || !windows.includes(t.w) || !dest || dest === t.w || !windows.includes(dest)) return false;
|
||||
const src = t.w;
|
||||
withWin(src, () => {
|
||||
if (fsTabId === id) leaveHtmlFullscreen(t, true);
|
||||
const mine = winTabs();
|
||||
const i = mine.indexOf(t);
|
||||
const next = mine[i + 1] || mine[i - 1];
|
||||
try { win.contentView.removeChildView(t.view); } catch {}
|
||||
t.w = null; // between windows
|
||||
if (next) { if (activeId === id) setActive(next.id); else emitTabs(); }
|
||||
});
|
||||
t.w = dest;
|
||||
// After the destination window's last tab in the shared list.
|
||||
tabs.splice(tabs.indexOf(t), 1);
|
||||
const there = winTabs(dest);
|
||||
tabs.splice(there.length ? tabs.indexOf(there[there.length - 1]) + 1 : tabs.length, 0, t);
|
||||
try { dest.win.contentView.addChildView(t.view); } catch {}
|
||||
withWin(dest, () => {
|
||||
if (curW === primaryW && leftPanelKey() && settings.sidebarPanelMode !== "push") raisePanelGrip();
|
||||
setActive(id);
|
||||
layout();
|
||||
});
|
||||
if (!winTabs(src).length) { try { src.win.close(); } catch {} }
|
||||
try { dest.win.show(); dest.win.focus(); t.view.webContents.focus(); } catch {}
|
||||
return true;
|
||||
}
|
||||
function closeTab(id) {
|
||||
const owner = tabById(id)?.w;
|
||||
if (owner && owner !== curW) return withWin(owner, () => closeTabHere(id));
|
||||
|
|
@ -5811,6 +5842,16 @@ ipcMain.handle("tab-detach", (e, tabId, x, y) => {
|
|||
const b = win.getBounds();
|
||||
const inside = px >= b.x && px < b.x + b.width && py >= b.y && py < b.y + b.height;
|
||||
if (inside && py < b.y + CHROME_H + 24) return false;
|
||||
// Let go over another window's toolbar: the tab joins that window. Only
|
||||
// when the point is off its own window, which is the one on top while the
|
||||
// tab is dragged from it.
|
||||
if (!inside) {
|
||||
for (const w of windows) {
|
||||
if (w === curW || !w.win || w.win.isDestroyed() || w.win.isMinimized()) continue;
|
||||
const wb = w.win.getBounds();
|
||||
if (px >= wb.x && px < wb.x + wb.width && py >= wb.y && py < wb.y + (w.chromeH || 84) + 24) return moveTabToWindow(t.id, w);
|
||||
}
|
||||
}
|
||||
return moveTabToNewWindow(t.id, { x: px, y: py });
|
||||
});
|
||||
ipcMain.handle("tab-context-menu-popup", (e, tabId, rect) => {
|
||||
|
|
@ -5850,6 +5891,12 @@ ipcMain.handle("tab-context-menu-popup", (e, tabId, rect) => {
|
|||
{ label: "Reload", click: () => { try { t.view.webContents.reload(); } catch {} } },
|
||||
{ label: "Duplicate", click: () => { if (t.url) createTab(t.url, { after: t.id }); else createTab(null, { after: t.id }); } },
|
||||
{ label: "Move to new window", enabled: winTabs(t.w).length > 1, click: () => moveTabToNewWindow(t.id) },
|
||||
...(windows.length > 1 ? [{ label: "Move to window", submenu: windows.filter((w) => w !== t.w).map((w) => {
|
||||
const front = tabById(w === curW ? activeId : w.activeId);
|
||||
const n = winTabs(w).length;
|
||||
const name = String(front?.title || front?.url || "Window").slice(0, 60);
|
||||
return { label: n > 1 ? `${name} (and ${n - 1} more)` : name, click: () => moveTabToWindow(t.id, w) };
|
||||
}) }] : []),
|
||||
{ label: "Group", submenu: groupSubmenu },
|
||||
{ label: "Add to Bookmarks", enabled: !bmDisabled, click: () => {
|
||||
if (bmDisabled) return;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue