Summary
Add split view — open two documents side by side in the same window. This is the "compare" primitive (Word's View side by side): review a contract against its previous version, a proposal against its template, a deck against the brief.
Motivation
- Document work is inherently comparative; today the only options are switching tabs (loses context) or opening a second window.
- The tab system already keeps every tab as its own
WebContentsView (apps/shell/src/main/tab-manager.ts) — only the active one is visible. Split view is a layout change on top of that model: two views visible with a draggable divider. No engine work, no new document model.
- Familiar pattern for office users (Word, Google Docs both have side-by-side) → does not hurt intuitiveness; it reduces context-switch friction.
Proposed UX
- Drag a tab onto the edge of the editor area → splits horizontally or vertically (drop indicator shows which).
- Alternatively: right-click tab → "Split left / Split right / Split above / Split below".
- Divider draggable; double-click resets to 50/50. Active split highlighted in the tab bar; each split shows its own scroll/zoom state.
- Close a split by dragging its tab back to the tab bar or via the tab's close button (closes the pane, not the file).
- Keyboard:
Cmd/Ctrl+\ toggles split of the current tab; Cmd/Ctrl+1/2 focuses first/second pane (proposal).
- State is per-window and not persisted across restarts (v1) — keep it simple.
Implementation notes
- Layout model: extend
apps/shell/src/main/tab-manager.ts (or add a layout-manager.ts) from "one active visible view" to "a split tree" — minimal viable v1: a single split (2 panes), each pane holding one TabRecord. Reuse existing setBounds/resize logic (contentBounds(), trackHtmlFullScreen).
- Renderer:
apps/shell/src/renderer/src/TabBar.tsx needs drop-target affordances; AppFrame.tsx renders the split state (which tabs are visible + divider position).
- IPC: extend
TABS_CHANNELS (tabs:split, tabs:unsplit, tabs:set-divider, focus events) in apps/shell/src/shared/tabs-api.ts + preload.
- The AI panel: with a split, the panel should attach to the focused pane (session continuity per document already works via
chatId — verify the panel doesn't assume a single active doc).
- Do not touch the apps (
apps/{docs,sheets,slides,pdf}) unless the AI-panel focus issue forces a small, well-scoped change.
Acceptance criteria
Out of scope
- More than 2 panes, persisted layouts, split-scrolling sync (scroll one, mirrors other), side-by-side inside a single document (diff view) — those are follow-ups.
Summary
Add split view — open two documents side by side in the same window. This is the "compare" primitive (Word's View side by side): review a contract against its previous version, a proposal against its template, a deck against the brief.
Motivation
WebContentsView(apps/shell/src/main/tab-manager.ts) — only the active one is visible. Split view is a layout change on top of that model: two views visible with a draggable divider. No engine work, no new document model.Proposed UX
Cmd/Ctrl+\toggles split of the current tab;Cmd/Ctrl+1/2focuses first/second pane (proposal).Implementation notes
apps/shell/src/main/tab-manager.ts(or add alayout-manager.ts) from "one active visible view" to "a split tree" — minimal viable v1: a single split (2 panes), each pane holding oneTabRecord. Reuse existingsetBounds/resize logic (contentBounds(),trackHtmlFullScreen).apps/shell/src/renderer/src/TabBar.tsxneeds drop-target affordances;AppFrame.tsxrenders the split state (which tabs are visible + divider position).TABS_CHANNELS(tabs:split,tabs:unsplit,tabs:set-divider, focus events) inapps/shell/src/shared/tabs-api.ts+ preload.chatId— verify the panel doesn't assume a single active doc).apps/{docs,sheets,slides,pdf}) unless the AI-panel focus issue forces a small, well-scoped change.Acceptance criteria
Out of scope