Skip to content

[BUG] Desktop app chat scroll jumps/skips content during fast upward scrolling #17996

Closed as not planned

Description

@cpkt9762

Description

When scrolling upward through the chat history in the desktop app, the viewport occasionally jumps forward (downward) by a large amount — effectively skipping an entire page of content. This happens most reliably during fast trackpad scrolling when there is a long message history.

Root cause (identified in source):

createSessionHistoryWindow.preserveScroll in packages/app/src/pages/session.tsx captures beforeTop = el.scrollTop at the time backfillTurns is triggered, then uses it in a requestAnimationFrame callback to restore scroll position after prepending messages.

The problem: native scroll events continue to fire between the initial capture and the rAF callback. By the time rAF runs, the user has scrolled further, but el.scrollTop is forcibly reset to the stale beforeTop + delta — which is ahead of where the user has actually scrolled to.

```ts
// packages/app/src/pages/session.tsx ~line 128
const preserveScroll = (fn: () => void) => {
const el = input.scroller()
const beforeTop = el.scrollTop // ← captured at event time (e.g. scrollTop = 100)
const beforeHeight = el.scrollHeight
fn() // ← DOM mutation: prepends ~8 messages (+D px)
requestAnimationFrame(() => {
const delta = el.scrollHeight - beforeHeight
if (!delta) return
el.scrollTop = beforeTop + delta // ← rAF fires later; user has scrolled to 20,
// but this resets to 100 + D → JUMP
})
}
```

Secondary factor: when userScrolled = true, create-auto-scroll.tsx sets overflow-anchor: auto on the scroller, so the browser already compensates for the prepended content automatically. The preserveScroll rAF then applies a second overlapping correction using the stale beforeTop, making the jump worse.

Proposed minimal fix:

```ts
const preserveScroll = (fn: () => void) => {
const el = input.scroller()
if (!el) { fn(); return }
const prev = el.style.overflowAnchor
el.style.overflowAnchor = "none" // disable browser auto-compensation
const beforeHeight = el.scrollHeight
fn()
requestAnimationFrame(() => {
const delta = el.scrollHeight - beforeHeight
el.style.overflowAnchor = prev
if (!delta) return
el.scrollTop += delta // add delta to current scrollTop, not stale one
})
}
```

Plugins

none

OpenCode version

v1.2.27

Steps to reproduce

  1. Open a session with long message history (10+ turns)
  2. With a trackpad, scroll upward quickly through the chat
  3. When scrollTop drops below ~200px, backfillTurns fires and prepends 8 messages
  4. Observe the viewport jump forward (downward) by a page or more

Screenshot and/or share link

No screenshot — reproducible by fast trackpad scroll in any long session

Operating System

macOS 26.2

Terminal

N/A (Desktop app)

Activity

  1. added a commit that references this issue on Mar 21, 2026
    aece29f
  2. removed
    webRelates to opencode on web / desktop
    on May 3, 2026
  3. arefks commented on Jun 8, 2026

    @arefks

    Still not fixed completely.

  4. 817811770 commented on Aug 3, 2026

    @817811770

    A fix for the desktop/web scroll-snap issue has been submitted: #40323 (Closes #40322). Verified locally on Windows: scroll up during a streaming response now holds position, and auto-follow resumes when returning to the bottom. If you are affected by this bug, a reaction or comment on the PR helps it stay open.

  5. github-actions commented on Oct 4, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions