fix: preserve scroll position when new output arrives#150
Conversation
When the user has scrolled up to review earlier output, keep the viewport locked on the same content as new lines arrive instead of snapping back to the bottom. Save the scrollback length before each write and adjust `viewportY` by the delta afterward. Clamp to the current scrollback length in case old lines are dropped by the buffer limit. When the user is already at the bottom (`viewportY === 0`), the adjustment is skipped and the viewport naturally follows new output. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Cross-validated against
One change folds both fixes in: if (savedViewportY > 0) {
const newScrollback = this.wasmTerm!.getScrollbackLength();
const delta = Math.max(0, newScrollback - savedScrollback);
const newViewportY = Math.min(savedViewportY + delta, newScrollback);
if (newViewportY !== savedViewportY) {
this.viewportY = newViewportY;
this.scrollEmitter.fire(this.viewportY);
if (newScrollback > 0) this.showScrollbar();
}
}Also worth a unit test pinning the scrollback-eviction clamp — |
|
Accepted most of this, just moved the new max guard to newViewportY since that feels a bit more correct. |
Adjust
viewportYby the scrollback delta so the viewport stays locked on the same content while output streams below. Clamp to the current scrollback length in case old lines are dropped by the buffer limit.