Tabs like mailternal; remove the note route's titlebar band #30

Open
opened 2026-09-15 16:14:21 +00:00 by kayg · 5 comments
Owner

Request (user, 2026-09-15)

Port mailternal's tabs (~/Developer/mailternal/App/Sources/Tabs: ReaderTabs, ReaderTabBar, ReaderTabItem, ReaderTabsPolicy, ReaderTabsSnapshot, ReaderTabHoverCard) to Calternal: any item (note, event, day) opens as a tab in the top row; ⌘-click/middle-click opens beside the current tab; ⌘T/⌘W; drag to reorder; hover card; browser-like. Tab set persists per Space (DECISIONS.md #20). Also: with a note open a 'titlebar band' appears that no other route has — find the view the note route adds and remove it; the shell must be identical on every route (window is already unified/hidden-title).

## Request (user, 2026-09-15) Port mailternal's tabs (~/Developer/mailternal/App/Sources/Tabs: ReaderTabs, ReaderTabBar, ReaderTabItem, ReaderTabsPolicy, ReaderTabsSnapshot, ReaderTabHoverCard) to Calternal: any item (note, event, day) opens as a tab in the top row; ⌘-click/middle-click opens beside the current tab; ⌘T/⌘W; drag to reorder; hover card; browser-like. Tab set persists per Space (DECISIONS.md #20). Also: with a note open a 'titlebar band' appears that no other route has — find the view the note route adds and remove it; the shell must be identical on every route (window is already unified/hidden-title).
Author
Owner

Worker TabsShell (worktree /home/kayg/Developer/calternal-apple/.worktrees/tabs-shell, branch wave19/tabs-shell) completed the tabs-shell lane.

Implemented in commit dc766de:

  • Added native Calternal tab hover card/popover with reduced-motion handling.
  • Added command-click and middle-click sidebar row routing through the canonical selection -> tabs model -> route path.
  • Added Cmd-T, Cmd-W, and Cmd-Shift-[ / ] shortcuts.
  • Removed the note navigation filename header that created the note-only top band.
  • Added Calternal tabs policy/snapshot unit coverage.

Validation: worktree is clean after commit. Scripts/build-mbp.sh tabs-shell app was launched; result pending at handoff. VM verification is deferred to the parent because the parent controls the VM lease and scripted QA queue.

Worker TabsShell (worktree `/home/kayg/Developer/calternal-apple/.worktrees/tabs-shell`, branch `wave19/tabs-shell`) completed the tabs-shell lane. Implemented in commit `dc766de`: - Added native Calternal tab hover card/popover with reduced-motion handling. - Added command-click and middle-click sidebar row routing through the canonical selection -> tabs model -> route path. - Added Cmd-T, Cmd-W, and Cmd-Shift-[ / ] shortcuts. - Removed the note navigation filename header that created the note-only top band. - Added Calternal tabs policy/snapshot unit coverage. Validation: worktree is clean after commit. `Scripts/build-mbp.sh tabs-shell app` was launched; result pending at handoff. VM verification is deferred to the parent because the parent controls the VM lease and scripted QA queue.
Author
Owner

Worker correction: commit f87ea5f adds the missing declaration terminator in SidebarTableControl after the cmd/middle-click callback patch. The app build is now running correctly from inside the tabs-shell worktree with worktree argument tabs-shell; cold builds can be silent for up to 10 minutes. Initial build attempt was cancelled after an incorrect path invocation and did not produce BUILT_APP.

Worker correction: commit `f87ea5f` adds the missing declaration terminator in SidebarTableControl after the cmd/middle-click callback patch. The app build is now running correctly from inside the tabs-shell worktree with worktree argument `tabs-shell`; cold builds can be silent for up to 10 minutes. Initial build attempt was cancelled after an incorrect path invocation and did not produce BUILT_APP.
Author
Owner

VM evidence (Main, 2026-09-16 overnight, tabs-shell @ 869f1c2d): tab strip appears in the unified top row after File → Open Selection in New Tab (/tmp/vm/tabs-final/three-tabs.png). Root cause of the earlier 'no strip': toolbar tab item visibilityPriority .low → hidden. Follow-ups: (1) with 4 tabs the +/search/inspector items overflow into » — mailternal keeps them visible (flexible spaces + tab strip shrink/scroll); (2) ⌘-click / middle-click on sidebar rows could not be exercised via cua-driver (modifier flags not delivered to NSTableView) — verify on the desktop.

VM evidence (Main, 2026-09-16 overnight, tabs-shell @ 869f1c2d): tab strip appears in the unified top row after File → Open Selection in New Tab (/tmp/vm/tabs-final/three-tabs.png). Root cause of the earlier 'no strip': toolbar tab item visibilityPriority .low → hidden. Follow-ups: (1) with 4 tabs the +/search/inspector items overflow into » — mailternal keeps them visible (flexible spaces + tab strip shrink/scroll); (2) ⌘-click / middle-click on sidebar rows could not be exercised via cua-driver (modifier flags not delivered to NSTableView) — verify on the desktop.
Author
Owner

Overnight (Main): merged tabs at 869f1c2d (strip works, File → Open Selection in New Tab, ⌘T/⌘W/⌘⇧[], per-Space restore). 2db5e406 (toolbar overflow + duplicate-focus polish) NOT merged: on the VM it made the strip disappear after five opens (/tmp/vm/tabs-main-five.png) — the equivalence check likely collapses distinct events. Follow-ups: trailing toolbar items overflow into » with 4+ tabs; dedupe on reopen; ⌘-click/middle-click untestable via cua (verify on desktop).

Overnight (Main): merged tabs at 869f1c2d (strip works, File → Open Selection in New Tab, ⌘T/⌘W/⌘⇧[], per-Space restore). 2db5e406 (toolbar overflow + duplicate-focus polish) NOT merged: on the VM it made the strip disappear after five opens (/tmp/vm/tabs-main-five.png) — the equivalence check likely collapses distinct events. Follow-ups: trailing toolbar items overflow into » with 4+ tabs; dedupe on reopen; ⌘-click/middle-click untestable via cua (verify on desktop).
Author
Owner

Overnight (Main): merged build fix Size the tab strip from its toolbar position — the strip was sized from the viewer column's leading edge (x≈390) while the toolbar places it after the sidebar separator (x≈430); the ~30 pt over-allocation pushed +/search into the » overflow after closing a tab. VM: open×4 / close / reorder / relaunch all keep trailing items in place (/tmp/vm/suite/tabs2/{three-tabs,after-close,after-reorder}.png). Also removed the duplicate SwiftUI ⌘W shortcut (the key monitor is the single handler; mailternal lets the menu own it — FOLLOW-UP for parity). Note: tabs_check.py reports tabs=0 because cua-driver 0.28.1 get_window_state no longer returns identifiers/labels — checker debt, screenshots are the evidence.

Overnight (Main): merged build fix `Size the tab strip from its toolbar position` — the strip was sized from the viewer column's leading edge (x≈390) while the toolbar places it after the sidebar separator (x≈430); the ~30 pt over-allocation pushed `+`/search into the `»` overflow after closing a tab. VM: open×4 / close / reorder / relaunch all keep trailing items in place (/tmp/vm/suite/tabs2/{three-tabs,after-close,after-reorder}.png). Also removed the duplicate SwiftUI ⌘W shortcut (the key monitor is the single handler; mailternal lets the menu own it — FOLLOW-UP for parity). Note: `tabs_check.py` reports tabs=0 because cua-driver 0.28.1 `get_window_state` no longer returns identifiers/labels — checker debt, screenshots are the evidence.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal-macos#30
No description provided.