Skip to content

fix(vscode): keep session scroll pinned during layout corrections - #13273

Merged
marius-kilocode merged 2 commits into
mainfrom
investigate-session-scroll-regression
Aug 20, 2026
Merged

fix(vscode): keep session scroll pinned during layout corrections#13273
marius-kilocode merged 2 commits into
mainfrom
investigate-session-scroll-regression

Conversation

@marius-kilocode

@marius-kilocode marius-kilocode commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

Session auto-follow can stop during streaming when virtualized layout corrections move scrollTop without changing scrollHeight. The transcript then remains above the live output even though the user did not scroll.

This change keeps unmarked layout corrections in follow mode while preserving deliberate user scrolling across the transcript, PromptRail, keyboard, touch, pointer, and nested scroll containers.

Regression History

PR #13009, initial scroll stabilization

PR #13009, fix(ui): prevent snap-to-bottom and flickering during upward session scroll, merged on August 7, addressed the earlier snap-to-bottom and flicker behavior. Its implementation changed createAutoScroll and createUserActivity and introduced the input-aware distinction between user scrolling and layout-driven movement.

The relevant commits were:

  • c514c08749, initial scroll stabilization.
  • f1e5ed30e4, replaced the stop debounce with synchronous scroll-state handling.

That work correctly stopped content resizing from fighting an active upward scroll, but it left a difficult distinction: native scrollbar movement can produce a scroll event without an easily observable input event.

PR #13160, streaming follow-up

PR #13160, fix(ui): preserve streaming chat scroll position, merged on August 17, addressed streaming output, virtualizer measurement, browser anchoring, downward wheel input, native scrollbar movement, and long touch gestures.

The relevant commits were:

  • cba6ebc6fa, added the streaming scroll-position handling.
  • 2acdb46eee, added the native scroll pause behavior.

PR #13160 added a stable-height movement heuristic to cover the native-scrollbar case. The heuristic compared the previous and current scrollTop and scrollHeight values and treated a position change with stable content height as intentional user movement.

Current Regression

The stable-height condition is not sufficient to identify user input. Virtua and browser layout code can correct scrollTop during virtualized row measurement, scroll anchoring, or layout reflow while scrollHeight remains unchanged.

The failure sequence is:

  1. The session is following the bottom while output streams.
  2. A virtualized row or layout correction moves scrollTop upward.
  3. The correction emits a scroll event before the resize observer restores bottom-follow.
  4. The stable-height heuristic classifies that correction as user scrolling.
  5. Auto-follow enters the paused state.
  6. More streamed output increases the content height, but the paused state prevents the transcript from returning to the bottom.

The visible result is intermittent: the session scrolls correctly in most cases, then stops following after a layout correction. The problem is more likely with long transcripts, virtualized rows, tool output, tables, charts, throughput updates, and other content that changes height while streaming.

There was also a separate integration path in which PromptRail directly changed the transcript scrollTop from a sibling element. Removing the heuristic would otherwise lose that user-intent signal, so this change handles PromptRail explicitly.

Fix

  • Remove stable-height scrollTop movement as an implicit user-intent signal.
  • Keep unmarked programmatic and layout-generated corrections in auto-follow mode.
  • Preserve explicit wheel, pointer, touch, and keyboard input tracking.
  • Route body-targeted keyboard scrolling to the deepest registered container that can scroll in the requested direction.
  • Allow keyboard scrolling to fall through from a nested container at its scroll boundary.
  • Explicitly pause the transcript when PromptRail forwards upward wheel movement, with the same overflow guard used by direct scroll input.
  • Keep nested scroll-container ownership and listener cleanup isolated.

The key rule is now: layout movement alone does not pause auto-follow; observable user input does.

Behavior

  • Streaming content remains pinned to the bottom through virtualized layout corrections and reflows.
  • An upward wheel or trackpad gesture pauses follow immediately.
  • PromptRail upward scrolling pauses follow and preserves the reading position as new output arrives.
  • Downward scrolling at the bottom does not detach follow mode.
  • Pointer and touch interactions continue to detach follow mode.
  • Keyboard scrolling works for ArrowUp, ArrowDown, PageUp, PageDown, Home, End, and Space, including nested scroll containers.
  • The scroll-to-bottom action can resume follow mode after a deliberate user scroll.
  • Native scrollbar behavior relies on the browser-delivered pointer interaction rather than inferring intent from stable content height.

Reproduction

A deterministic reproduction is:

  1. Open a long streaming session with virtualized transcript rows.
  2. Keep the transcript at the bottom while output is growing.
  3. Trigger a layout correction that changes scrollTop without changing scrollHeight.
  4. Append more streamed output.
  5. Before this change, the transcript remains above the new output and requires manual recovery.
  6. After this change, the correction is ignored as user intent and the transcript returns to the bottom.

PromptRail reproduction:

  1. Open a long session with the prompt rail visible.
  2. Scroll upward with the rail.
  3. Append more output.
  4. The transcript remains at the user-selected position instead of snapping back to the bottom.

Scope

The existing @kilocode/kilo-ui patch changeset is updated for this follow-up. Regression coverage lives at the hook level and in the VS Code webview Storybook/Chromium path.

@marius-kilocode
marius-kilocode merged commit 2f972fc into main Aug 20, 2026
34 of 35 checks passed
@marius-kilocode
marius-kilocode deleted the investigate-session-scroll-regression branch August 20, 2026 11:48
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