Skip to content

Scroll split windows independently#274

Merged
edwin-zvs merged 2 commits into
mainfrom
tui-independent-split-scroll
May 30, 2026
Merged

Scroll split windows independently#274
edwin-zvs merged 2 commits into
mainfrom
tui-independent-split-scroll

Conversation

@edwin-zvs

Copy link
Copy Markdown
Contributor

Summary

  • keep split-window PTY scrollback offsets per window instead of sharing one global offset
  • route mouse-wheel scrollback to the split under the cursor and focus that split
  • render each split using its own stored scrollback offset

Tests

  • cargo test -p agentd-cli mouse_scrollback_targets_only_hovered_split
  • cargo test -p agentd-cli switch_focus_cycles_list_then_first_split_window
  • cargo test -p agentd-cli mouse_list_click_updates_active_split_selection
  • cargo check -p agentd-cli
  • cargo build
  • git diff --check

Binaries

Built in this worktree under /Users/moon/agentd/.claude/worktrees/tui-independent-split-scroll/target/debug/.
Relevant binary for this PR: agent (crates/cli).

@edwin-zvs
edwin-zvs merged commit aab1b01 into main May 30, 2026
1 check passed
@edwin-zvs
edwin-zvs deleted the tui-independent-split-scroll branch May 30, 2026 18:53
edwin-zvs added a commit that referenced this pull request May 30, 2026
PR #274 made scroll offsets per-window in `window_scrollback`, keyed on
the active window id. Render always goes through `render_main_windows`
→ `render_terminal_for_window` and passes `Some(window_id)` even when
the main-window tree is a single Leaf, so it reads
`window_scrollback[active_window_id]`. The scroll handlers, however,
conditioned on `is_split_layout()` and used `None` whenever the tree
wasn't a real split — writing to `view_scrollback` instead of
`window_scrollback`. In single-pane mode the scrollbar appeared
(the mirror got updated) but the viewport never moved because render
read from the empty per-window store. Split layouts worked because
both sides keyed on `Some(window_id)`.

Drop the `is_split_layout()` gate at every scroll-handler call site —
keystroke snap, keyboard scroll, mouse wheel, scrollbar drag,
ScrollTop / ScrollBottom — so the scroll path keys on the same
`Some(active_window_id)` the render path uses.
`set_scrollback_for_window` already mirrors the write into
`view_scrollback` when `window_id == active_window_id`, so the zoomed
render path (which reads `view_scrollback`) still works.

Add `scroll_in_single_pane_updates_what_render_reads` as a regression
guard, and update `pty_keystroke_snapping_scrollback_still_redraws` to
set up state via the canonical `set_scrollback_for_window` instead of
mutating the now-mirror-only `view_scrollback` field directly.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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