Skip to content

Render one symbol per Claude pane within each tab#6

Open
anateus wants to merge 3 commits intoishefi:mainfrom
anateus:main
Open

Render one symbol per Claude pane within each tab#6
anateus wants to merge 3 commits intoishefi:mainfrom
anateus:main

Conversation

@anateus
Copy link
Copy Markdown

@anateus anateus commented Apr 27, 2026

Summary

Tabs with multiple Claude panes used to flicker between activity states because the renderer picked one "best" session per tab. Each pane now gets its own symbol slot.

Per-pane symbols

  • One symbol per Claude pane, ordered stably by pane_id so the layout doesn't reshuffle as activity changes.
  • Each symbol is rendered in a fixed 2-col cell so wide glyphs (⚡ ⚙ ▶ ⚠) and narrow glyphs no longer cause tab width to flicker as activity transitions.
  • Each symbol is its own click target that focuses that pane; the tab name still switches tabs. Waiting flashes are scoped to the affected symbol instead of pulsing the whole tab.
  • Adaptive name length: budget = (cols − fixed) / count, capped at 20. Names truncate when tight, drop when very tight; symbols stay visible.

Settings

  • Drops the elapsed_time setting (ambiguous which pane it'd refer to with multi-pane). Existing configs with the field still parse — serde ignores unknown keys.

Reliability fixes (review feedback)

  • render_tabs overflow guard now uses the actual per-tab fixed width and reserves the closing-arrow column. Wide tabs can no longer overflow into the next tab or register click regions for off-screen cells.
  • merge_sessions compares last_ts_ms when either side has it, falling back to last_event_ts only for old payloads. Per-pane rendering made same-second drops user-visible.
  • Symbol click regions are tight to the symbol cell — separator gaps no longer focus the previous pane.

Plumbing

  • ClickRegion refactored from (tab_index, pane_id, is_waiting) to a ClickAction { FocusPane | SwitchTab } enum.
  • README updated to describe per-pane symbols and per-symbol click semantics; replaces stale "elapsed time" row with the existing "mode indicator" toggle.
  • Version bumped to 0.5.1.

Test plan

  • Builds clean for wasm32-wasip1 (release + clippy)
  • Loaded into a live Zellij session with multiple Claude panes per tab; symbols render per pane in stable order, no flicker
  • Tab width is stable as Bash (⚡, wide) starts and stops
  • Verify per-symbol flash pulses only the waiting pane's symbol on a tab with several active Claude panes
  • Verify clicking the warning symbol focuses the waiting pane
  • Verify clicking the tab name switches tabs
  • Verify name adapts (truncates / drops) on a narrow terminal

anateus added 3 commits April 26, 2026 19:10
Tabs with multiple Claude panes previously flickered between activity
states because the renderer picked one "best" session per tab. Now every
pane gets its own symbol slot, ordered by pane_id so the layout is
stable as activity changes. Each symbol is its own click target that
focuses that pane; the tab name still switches tabs. Waiting flashes
are scoped to the affected symbol instead of the whole tab.

Drops the elapsed-time setting (ambiguous which pane it'd refer to) and
refactors ClickRegion to a ClickAction enum.
- render_tabs: replace the +3 fit guard with one based on per_tab_fixed
  so wide tabs (many panes) can no longer overflow into the next tab
  or register click regions for off-screen cells. Reserve the closing
  arrow column. Also gate name rendering on remaining space so a long
  name can't push past cols when symbols already filled the budget.
- Tighten symbol click regions to the symbol cell only; the separator
  space between symbols is now an unclaimed gap rather than bleeding
  into the previous pane's target.
- merge_sessions: compare last_ts_ms when either side has it, falling
  back to last_event_ts only for old payloads. Per-pane rendering made
  same-second drops user-visible.
- README: drop elapsed-time mentions, replace the now-stale "smart pane
  focus" line with the per-symbol click description, and document the
  mode-indicator setting that replaced elapsed-time in the menu.
Wide symbols (⚡ ⚙ ▶ ⚠ render as 2 cols in most terminals) used to
make the tab width flicker as activity transitioned between wide and
narrow glyphs. Each symbol now occupies a fixed 2-col cell: wide ones
fill it natively, narrow ones get a 1-col trailing pad. Tab width is
constant regardless of which mix of activities is active.

Trade-off is a 1-col gap variance between adjacent symbols (wide-then-X
has a 1-col gap, narrow-then-X has 2). Acceptable in exchange for no
flicker, and click targets are now uniformly 2 cols.

Bump to 0.5.1.
@anateus
Copy link
Copy Markdown
Author

anateus commented Apr 27, 2026

With multiple panes displaying all the elapsed times is a bit cumbersome so I decided to drop it, but obviously that's easy to adjust/revert. Just wanted to mention that it was intentional :)

@ishefi
Copy link
Copy Markdown
Owner

ishefi commented May 4, 2026

Thanks for this, it's the more complete take. Fixed-width symbol cells, per-symbol click regions via the new ClickAction enum, scoped flash, and the merge_sessions last_ts_ms fix all land cleanly together. Two things before merge:

  1. Ordering. Sorting by pane_id is stable but doesn't match what the user sees in the tab. PR feat: render multiple status icons per one tab #9 sorts by pane geometry (pane_y, pane_x) from pane_manifest, filtering is_plugin panes. Could you adopt that? pane_id ordering is arbitrary from the user's POV; geometry is what they expect.
  2. Dropping elapsed_time. I get the ambiguity argument, but PR feat: render multiple status icons per one tab #9 keeps it for the single-session case, which is still useful for spotting stuck sessions. Worth preserving with sessions.len() == 1 rather than removing the setting outright.

Otherwise lgtm. The README + version bump + addressed review feedback make this the cleaner base to land.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants