diff --git a/main.js b/main.js index d45a9270..a56505fd 100644 --- a/main.js +++ b/main.js @@ -3022,18 +3022,19 @@ function layout() { quickPanel.setBounds({ x: leftW, y: chromeH, width: quickW, height: bodyH }); try { quickPanel.setVisible(quickW > 0); } catch {} } - // An add-on's left panel; widened, it leaves the tabs a strip, like the - // right sidebar maximized. - const addonLeftW = (leftPanel && leftPanelId && !fsTab) - ? (leftPanelMax ? Math.max(LEFT_PANEL_W, width - leftW - 120) : LEFT_PANEL_W) : 0; - if (leftPanel) { - leftPanel.setBounds({ x: leftW, y: chromeH, width: addonLeftW, height: bodyH }); - try { leftPanel.setVisible(addonLeftW > 0); } catch {} - } - const panelW = quickW || addonLeftW; // Sidebar (when visible) claims a fixed slice on the right; the tab views // shrink to fit alongside it. When hidden, tabs get the full width. const sideW = sidebarVisible && !fsTab ? sidebarW : 0; + // An add-on's left panel. Widened, it covers the tab area like a page of + // its own, up to the right sidebar, which keeps its width: the tabs keep + // their narrow-panel bounds underneath instead of being squeezed aside. + const addonLeftW = (leftPanel && leftPanelId && !fsTab) ? LEFT_PANEL_W : 0; + const addonLeftShownW = addonLeftW && leftPanelMax ? Math.max(LEFT_PANEL_W, width - leftW - sideW) : addonLeftW; + if (leftPanel) { + leftPanel.setBounds({ x: leftW, y: chromeH, width: addonLeftShownW, height: bodyH }); + try { leftPanel.setVisible(addonLeftShownW > 0); } catch {} + } + const panelW = quickW || addonLeftW; const tabX = leftW + panelW; const tabW = Math.max(0, width - tabX - sideW); for (const t of tabs) t.view.setBounds({ x: tabX, y: chromeH, width: tabW, height: bodyH }); @@ -3569,6 +3570,9 @@ function setActive(id) { // sidebar to its pre-max width so the tab is actually visible; the // user can re-maximize when they're done. if (switching && sidebarMaximized) setSidebarMaximized(false); + // A widened left panel covers the tabs; bringing any tab forward (a tab + // click, Settings, a new tab) narrows it back to a bar beside the page. + if (leftPanelMax) setLeftPanelMax(false); // Show the NEW active tab first, THEN hide the others. Reversing this // order eliminates the "no tab is visible" frame on switch that made the // tab strip flash — the compositor always has at least one tab view up. @@ -4583,12 +4587,16 @@ async function loadBns(t, id, host, rest, tld) { // The toolbar and our own home page only — home-preload is in every tab, and a // web page must not steer the active tab (or a Settings tab) from the background. ipcMain.handle("navigate", (e, input) => { - if (chrome && e.sender === chrome.webContents) return navigateTab(activeId, input); + if (chrome && e.sender === chrome.webContents) { + // Address-bar navigation is for the page, so a widened left panel steps aside. + if (leftPanelMax) setLeftPanelMax(false); + return navigateTab(activeId, input); + } if (!isHomePageSender(e.sender)) return; const t = tabs.find((x) => x.view.webContents === e.sender); return navigateTab(t ? t.id : activeId, input); }); -ipcMain.handle("search", (_e, q) => navigateTab(activeId, SEARCH(q))); +ipcMain.handle("search", (_e, q) => { if (leftPanelMax) setLeftPanelMax(false); return navigateTab(activeId, SEARCH(q)); }); ipcMain.handle("new-tab", () => createTab()); ipcMain.handle("close-tab", (_e, id) => closeTab(id)); ipcMain.handle("switch-tab", (_e, id) => setActive(id)); @@ -5130,13 +5138,21 @@ function setSidebarMaximized(next) { sidebarW = Math.max(SIDEBAR_W_MIN, Math.min(SIDEBAR_W_MAX, sidebarPreMaxW || SIDEBAR_W_DEFAULT)); } sidebarMaximized = wanted; + if (wanted && leftPanelMax) setLeftPanelMax(false); layout(); try { sidebar?.webContents.send("sidebar-max-change", sidebarMaximized); } catch {} return sidebarMaximized; } const isLeftSender = (e) => !!leftPanel && e.sender === leftPanel.webContents; function setLeftPanelMax(next) { + if (!!next === leftPanelMax) return leftPanelMax; leftPanelMax = !!next; + if (leftPanelMax) { + // One wide view at a time: a maximized right sidebar steps back, and the + // panel goes on top of tab views created since it opened. + if (sidebarMaximized) setSidebarMaximized(false); + try { win.contentView.removeChildView(leftPanel); win.contentView.addChildView(leftPanel); } catch {} + } layout(); try { leftPanel?.webContents.send("sidebar-max-change", leftPanelMax); } catch {} return leftPanelMax;