Skip to content

Auto-scroll stops working after manually scrolling and returning to bottom #29992

@derycklong

Description

@derycklong

Description

When the assistant is generating a response, auto-scroll works correctly only if the user never scrolls. If the user scrolls up (to read earlier content) and then scrolls back down to the bottom, auto-scroll ceases to function: new content continues to arrive but the viewport stays fixed, forcing the user to manually scroll down to see each update.

Steps to Reproduce

  1. Send a message that will produce a long response
  2. Let streaming begin - auto-scroll follows the output (working state)
  3. press PageUp (or mouse-scroll up) to view earlier messages
  4. press PageDown repeatedly (or scroll down) to return to the bottom
  5. Observe that new content appears below viewport - viewport does not auto-scroll

Expected Behavior

  • Auto-scroll should be paused when the user scrolls away from the bottom
  • Auto-scroll should resume when the user returns to the bottom (or a small threshold above it)
  • Position-based detection should be used, not event-type heuristics

Actual Behavior

The current code in internal/tui/components/chat/list.go uses event-type heuristics to decide whether to call GotoBottom().

After the user manually scrolls back to bottom, YOffset equals the old maxYOffset(). When SetContentLines() updates the content, maxYOffset() increases, but the internal guard "if YOffset > maxYOffset() { GotoBottom() }" is false. The viewport library itself skips the scroll.

The opencode-level GotoBottom() call is gated on UpdatedEvent matching only the exact last message - tool results, summary compaction, or any non-last-message update bypass the condition entirely.

The session-summary rerender path calls renderView() with no GotoBottom() at all.

Suggested Fix

File: internal/tui/components/chat/list.go

  1. Add an autoScroll field to messagesCmp (initialized true)
  2. Track scroll position after every manual scroll - set autoScroll = viewport.AtBottom() after keyboard and mouse wheel events
  3. Replace the event-type guard with "if m.autoScroll { viewport.GotoBottom() }"
  4. Add GotoBottom() to the session summary rerender

Environment

  • opencode version: latest
  • OS: Windows
  • Terminal: Windows Terminal

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions