mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-10 09:19:42 +02:00
feat(tabs): draw lineage lines as one tree for the selected tab's family
Lineage lines used to draw one glowing dashed bezier per parent/child pair, hanging below the tab strip, for every family at once. With a parent on row 3 of a wrapped strip and ten children below it, the curves crossed every lower row's tab names and ran through the terminal text. - One rounded orthogonal tree per spawning tab: every route starts at the parent, so siblings share a trunk. 1.5px, solid, 1px dark outline; only a working child's branch is dashed. - Routes run only through the gaps between tab rows, joined by a spine left of every row (computeLineageTree/computeLineageRows in constants.js), so they never cross a tab or reach the terminal. The vertical rail gets the same tree on its existing left track. - Only the selected tab's family is drawn (what it spawned, plus its parent and siblings). Selection redraws, and the strip's size transitionend redraws once more, since the active tab widens for ~150ms after the selection redraw. - The routing room is reserved by .session-tabs.lineage-tree, keyed on whether any lineage exists, never on the selection, so a tab switch never resizes the header or the PTY. - Colours stay per spawning tab, now claimed in strip order for every family so selection order never decides who gets the skin blue. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+16
-7
@@ -5241,6 +5241,9 @@ class CodemanApp {
|
||||
// strip scrolls horizontally, so a tab selected from the palette, a swipe,
|
||||
// Alt+N or a push notification could stay parked off-screen.
|
||||
this._scrollActiveTabIntoView(sessionId);
|
||||
// Lineage lines draw only the SELECTED tab's family (session-lineage.js), so a
|
||||
// selection change is a redraw whenever any lineage exists at all.
|
||||
if (this._lineageTotalEdges > 0) this.updateConnectionLines();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5633,13 +5636,15 @@ class CodemanApp {
|
||||
this._refreshHomeSessionsIfVisible?.();
|
||||
// The full-render path already redraws the connection SVG; this incremental
|
||||
// one does not, and a badge appearing widens a tab and shifts every tab after
|
||||
// it, sliding the lineage arcs off their anchors. Only pay for it when there
|
||||
// is something anchored to tab rects: lineage arcs, or — in a VERTICAL list
|
||||
// (sidebar, where lineage is skipped and the edge count stays 0, or the
|
||||
// rail, which can show connectors with zero lineage edges too) — the
|
||||
// subagent/ultracode connectors, whose rows a badge changes the HEIGHT of.
|
||||
// Same widening as the strip-scroll listener in session-lineage.js.
|
||||
if (this._lineageEdgeCount > 0 || this._isVerticalTabList()) this.updateConnectionLines();
|
||||
// it, sliding the lineage lines off their anchors. Only pay for it when there
|
||||
// is something anchored to tab rects: any lineage at all (not just what is
|
||||
// drawn now: a parentSessionId or a child's working state can arrive on this
|
||||
// path and change the selected family's tree), or, in a VERTICAL list (the
|
||||
// sidebar, where lineage is skipped, or the rail, which can show connectors
|
||||
// with zero lineage edges too), the subagent/ultracode connectors, whose
|
||||
// rows a badge changes the HEIGHT of. updateTabOverflowMode() above has just
|
||||
// refreshed _lineageTotalEdges.
|
||||
if (this._lineageTotalEdges > 0 || this._isVerticalTabList()) this.updateConnectionLines();
|
||||
|
||||
this.applySidebarFilter(this._sidebarFilter);
|
||||
}
|
||||
@@ -5651,6 +5656,10 @@ class CodemanApp {
|
||||
const container = this.$('sessionTabs');
|
||||
if (!container) return;
|
||||
|
||||
// Lineage routing room (session-lineage.js) changes the strip's padding and
|
||||
// row gap, so it is decided before the wrap is measured below.
|
||||
this._syncLineageGutter?.();
|
||||
|
||||
// The sidebar list is a single vertical column with its own scroller —
|
||||
// there is no row to overflow, and measuring it would fight the CSS.
|
||||
if (this.isSessionSidebarActive()) {
|
||||
|
||||
Reference in New Issue
Block a user