From 517e93b03c57d2bcd5b692b821ec8a9da0a929ba Mon Sep 17 00:00:00 2001 From: Max <112043822+Maxaubert@users.noreply.github.com> Date: Sun, 11 Oct 2026 23:16:07 +0200 Subject: [PATCH] feat: a clear title bar moves the window with vertical tabs, not the sidebar With vertical tabs and the title bar off, a row of the terminal's own ground over the terminal (no line, no name) holds the window buttons and moves the window; the sidebar's empty space no longer does. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_017XYVRPzvhLpPCr75uB6uaA --- .../specs/2026-10-11-vertical-tabs-design.md | 6 ++++ package-lock.json | 4 +-- package.json | 2 +- src/renderer/src/App.tsx | 35 +++++++++++-------- src/renderer/src/components/TabSidebar.tsx | 31 ++-------------- tools/e2e/run.mjs | 28 +++++++++++---- 6 files changed, 54 insertions(+), 52 deletions(-) diff --git a/docs/superpowers/specs/2026-10-11-vertical-tabs-design.md b/docs/superpowers/specs/2026-10-11-vertical-tabs-design.md index d254a3d..4c9cce3 100644 --- a/docs/superpowers/specs/2026-10-11-vertical-tabs-design.md +++ b/docs/superpowers/specs/2026-10-11-vertical-tabs-design.md @@ -57,6 +57,12 @@ looked at on the way). bar or some way to drag it"). The e2e asks Windows itself (WM_NCHITTEST) where a press moves the window. +- **A clear title bar, not the sidebar, moves the window** (owner: "there should be a title bar to + drag from not the sidebar. how about making it transparent"): with vertical tabs and the title bar + off, a 32 px row over the terminal only, in the terminal's own ground with no line and no name, + holds the window buttons and moves the window. The sidebar's empty space no longer does. With the + sidebar collapsed the row spans the window. + ## 2. The indicators - **Vertical tabs have no new look for the indicators** (owner: "vertical tabs shouldnt have a new diff --git a/package-lock.json b/package-lock.json index b5bd1e3..c634d2b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "prism-terminal", - "version": "0.39.4", + "version": "0.39.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "prism-terminal", - "version": "0.39.4", + "version": "0.39.5", "license": "MIT", "dependencies": { "@xterm/addon-fit": "^0.11.0", diff --git a/package.json b/package.json index 1270855..76294ad 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "prism-terminal", "productName": "Prism Terminal", - "version": "0.39.4", + "version": "0.39.5", "description": "A tabbed Windows terminal for AI CLIs.", "main": "./out/main/index.js", "author": "Max", diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index 13bcb72..d7ef133 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -721,6 +721,26 @@ export default function App(): JSX.Element { headStart={bare ? : undefined} /> )} +
+ {/* A TITLE BAR YOU CANNOT SEE (owner, 2026-10-11: "there should be a + title bar to drag from not the sidebar. how about making it + transparent"): with the tabs down the side and the title bar off, + the row over the terminal is the terminal's own ground, no line, no + name, and moves the window; the three window buttons (and the update + chip, when there is one) sit at its right. Over the terminal only, + so the sidebar keeps its tabs at the top; with the sidebar collapsed + that is the whole width. */} + {bare && ( +
+ {chip} +
+ +
+
+ )}
- {/* What is left of the title bar: the window's own three buttons, and - the update chip when there is one, always there and quiet ("either - buttons that show once your cursor is close or always persistent": - always, since a reveal at the edge is the thing that did not hold). - On the terminal's own ground, so a long first line runs under them - rather than through them. */} - {bare && ( -
- {chip} -
- -
-
- )} +
{termMenu && activeShell && termMenu.id === activeShell.id && ( void onReorder: (id: string, toIndex: number) => void onOpenRecent: (path: string) => void - /** The title bar is hidden: the sidebar's head is the window's handle. */ + /** The title bar is hidden: the sidebar starts at the window's top. */ titleRow: boolean /** Command help and Settings, at the foot, when there is no title bar. */ headStart?: ReactNode @@ -248,25 +248,6 @@ export function TabSidebar({ grip.addEventListener('pointercancel', up) } - // A drag in from Explorer (a folder for a new tab) is not a pointer: no - // pointermove arrives while it is in flight, so the head stops being a - // window handle for the length of it, as the strip does. - const [dragInFlight, setDragInFlight] = useState(false) - useEffect(() => { - const on = (): void => setDragInFlight(true) - const off = (): void => setDragInFlight(false) - window.addEventListener('dragenter', on, true) - window.addEventListener('dragend', off, true) - window.addEventListener('drop', off, true) - window.addEventListener('pointermove', off, true) - return () => { - window.removeEventListener('dragenter', on, true) - window.removeEventListener('dragend', off, true) - window.removeEventListener('drop', off, true) - window.removeEventListener('pointermove', off, true) - } - }, []) - if (!tabs.length) return null const labels = tabLabels(tabs) const auxClose = (e: MouseEvent, id: string): void => { @@ -275,9 +256,6 @@ export function TabSidebar({ onClose(id) } } - // Hidden off to the left, it is no handle and no stop for Tab: an element - // moved out of sight can still claim the window's drag region and the keys. - const handle = titleRow && visible && !dragInFlight ? 'drag' : 'no-drag' return (
{tabs.map((t, i) => { const on = t.id === activeId @@ -498,10 +476,7 @@ export function TabSidebar({ {/* THE BUTTONS, AT THE FOOT (owner, 2026-10-11): the +, then, with no title bar, command help and Settings, then the sidebar's own button. The space between them moves the window too. */} -
+