Skip to content

feat: scroll the left pane when the sessions outgrow it - #45

Merged
tkc merged 1 commit into
mainfrom
feat/sidebar-scroll
Oct 29, 2026
Merged

tkc merged 1 commit into
mainfrom
feat/sidebar-scroll

Conversation

@tkc

@tkc tkc commented Oct 29, 2026

Copy link
Copy Markdown
Owner

The session list dropped every row that did not fit: with fourteen sessions
open the last ones were simply not drawn, and a jump key could select a row
nobody could see.

Stacked on #44 — it rewrote sidebar_layout, which is exactly where this
lands. GitHub will retarget this to main once #44 merges.

What it does

  • The list starts at a row offset and scrolls. The wheel over the left pane
    moves it; it used to fall through to the selected terminal's scrollback,
    which is not what the pointer was on. When the cross-session hits are
    showing, the wheel moves those instead.
  • Switching sessions brings the selected row back into view.

Rows have different heights (the title line and the branch line are both
optional), so the offset counts tree rows and the placement walks the
measured heights. Three pure functions carry it, each with its own test:
sidebar_rows (what fits from an offset), sidebar_max_offset (the row that
puts the last one on the bottom edge — the wheel stops there rather than
scrolling into blank space), sidebar_follow (raise the offset until the
selected row is inside).

Following only happens when the selected row changes, not every frame.
Every frame would undo the wheel the moment the hand left it. The clamp to the
last usable offset does run every frame, since closing a session lowers it.

Two things the eye check caught

The visual gate is TERMIT_PROBE_OVERLAY=many cargo run --release -- --probe out.png, added here: 21 sessions, the last one selected, the list scrolled.

  1. The jump labels were wrong. They were taken from the position inside
    the window, so after scrolling ⌘1 sat on a row that ⌘1 does not select
    — against what the README promises. Now taken from the tree row.
  2. Drag-to-reorder has two coordinate systems that used to coincide.
    sidebar_boundary returns a position in the window; drop_row takes tree
    rows. With a non-zero offset a dragged row would land that many places
    away. sidebar_boundary now returns the tree row and sidebar_boundary_y
    converts back.

Also

Rows outside the window now reconcile shown_working. Leaving them stale made
wants_redraw ask for a full redraw on every byte a session nobody could see
printed — pre-existing for the cut-off rows, but this change owns them now.

Gates

cargo fmt --check clean, clippy --all-targets -D warnings silent,
308 passed; 0 failed; 2 ignored (7 new).

Not in this PR

No hint of how many rows are hidden above or below. The labels give it away
(⌘A at the top means you are nine rows down), and a counter is a separate
drawing change.

🤖 Generated with Claude Code

The session list dropped every row that did not fit. With fourteen
sessions open the last ones were simply not drawn, and a jump key could
select a row nobody could see.

The list now starts at a row offset and scrolls. Rows have different
heights — the title line and the branch line are both optional — so the
offset counts tree rows and the placement walks the measured heights:
sidebar_rows counts what fits from an offset, sidebar_max_offset stops
the wheel at the row that puts the last one on the bottom edge, and
sidebar_follow raises the offset until the selected row is inside.

The wheel over the left pane moves the list. It used to fall through to
the selected terminal's scrollback, which is not what the pointer was
on. When the cross-session hits are showing, it moves those instead.

Following happens only when the selected row changes, not every frame:
every frame would undo the wheel the moment the hand left it. The clamp
to the last usable offset does run every frame, since closing a session
lowers it.

Two coordinate systems meet in the drag-to-reorder path and used to
coincide. sidebar_boundary now returns the tree row rather than the
position inside the window, and sidebar_boundary_y converts back. The
jump label is taken from the tree row as well, so the key a row wears is
still the key that selects it.

Rows outside the window now reconcile shown_working too. Leaving them
stale made wants_redraw ask for a full redraw on every byte a session
nobody could see printed.

TERMIT_PROBE_OVERLAY=many renders the scrolled list for the eye check.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@tkc
tkc changed the base branch from feat/cross-session-search to main October 29, 2026 23:17
@tkc
tkc force-pushed the feat/sidebar-scroll branch from 316b581 to d758613 Compare October 29, 2026 23:17
@tkc
tkc merged commit d1b3539 into main Oct 29, 2026
2 checks passed
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.

1 participant