Skip to content

fix(desktop): keep terminal scroll position across bot switches - #7

Merged
ahilles107 merged 1 commit into
mainfrom
fix/terminal-scroll-position
Sep 10, 2026
Merged

ahilles107 merged 1 commit into
mainfrom
fix/terminal-scroll-position

Conversation

@ahilles107

Copy link
Copy Markdown
Owner

What

Switching bots no longer resets the terminal's scroll position. A pane that was parked mid-scrollback comes back exactly where the user left it, and the first wheel tick after a switch no longer snaps the buffer to the top of the scrollback.

Why

TerminalPane caches terminals and re-parents the same DOM element when the user switches bots. The browser resets a scrollable element's scrollTop the moment it leaves the document, so the restored pane painted the screen it had kept while .xterm-viewport reported being at offset 0. xterm then treated the next scroll input as starting from the top of the buffer.

The fix stores the viewport offset on the cache entry and restores it after re-attaching. The offset is only recorded while the viewport is still connected — detaching itself fires a scroll event reporting a position nobody scrolled to, and recording that would park the terminal at the top, which is the bug the change is meant to remove.

How tested

  • pnpm typecheck, pnpm lint, pnpm format:check, pnpm knip in apps/desktop — clean.
  • pnpm test in apps/desktop — 441 tests across 54 files pass.
  • New apps/desktop/src/components/TerminalPane.scroll.test.tsx covers both halves: the offset survives a detach/re-attach cycle, and the scroll-to-top event that accompanies detaching does not overwrite the stored offset. The test double for xterm now creates a real .xterm-viewport element, matching what xterm builds on open().

Notes

Branched from main of this repository rather than the archived gravity-private-archive remote the worktree still points at; the two share no history. A second local commit that bumped protocol_version to 2 in .claude/skills/terminal-perf-test/scripts/drive.mjs was dropped — that fix already exists here.

A cached terminal is re-parented when the user switches bots, and the
browser resets a scrollable element's offset the moment it leaves the
document. The pane painted the screen it had kept while its viewport
reported being at the top, so the first wheel tick after a switch snapped
the buffer back to the start of the scrollback.

Record the viewport offset while the element is still connected and
restore it after re-attaching, ignoring the scroll event that detaching
itself produces.
@ahilles107
ahilles107 merged commit 04494a3 into main Sep 10, 2026
6 checks passed
@ahilles107
ahilles107 deleted the fix/terminal-scroll-position branch September 10, 2026 00:25
ahilles107 added a commit that referenced this pull request Sep 10, 2026
Patch bump: everything since v0.12.4 is a fix or docs/tooling change with
no new or removed user-facing surface — the terminal keeps its scroll
position across bot switches (#7), the contributor skills were made safe
and portable (#4), and internal work moved to GitHub Issues (#6).
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