Skip to content

feat(cli): scroll the transcript three lines per wheel notch - #1274

Open
kavish-19 wants to merge 1 commit into
CodebuffAI:mainfrom
kavish-19:feat/wheel-scroll-three-lines
Open

feat(cli): scroll the transcript three lines per wheel notch#1274
kavish-19 wants to merge 1 commit into
CodebuffAI:mainfrom
kavish-19:feat/wheel-scroll-three-lines

Conversation

@kavish-19

@kavish-19 kavish-19 commented Sep 4, 2026

Copy link
Copy Markdown

Closes #1268.

The cause

The CLI never handles wheel events itself — OpenTUI's ScrollBoxRenderable does:

const multiplier = this.scrollAccel.tick(now)
const scrollAmount = baseDelta * multiplier

and the constructor defaults to LinearScrollAccel:

class LinearScrollAccel {
  tick(_now) { return 1 }
  reset() {}
}

A terminal reports one wheel notch as a delta of 1, so 1 × 1 moves the transcript a single line. That is the reported behaviour, and it's a default rather than a bug.

The change

ScrollBox already accepts a scrollAcceleration option (and exposes a setter), so nothing upstream needs changing — it's a prop on the existing <scrollbox> in chat.tsx. The React reconciler spreads JSX props straight into the renderable's constructor (createInstance in @opentui/react), which assigns the field the wheel handler reads.

Neither shipped accelerator gives a flat multiplier: LinearScrollAccel is fixed at 1, and MacOSScrollAccel ramps with scroll velocity, which would make a fast flick jump much further than the three lines the issue asks for. So this adds a small stateless ConstantScrollAccel. Because it's stateless there is nothing to accumulate or reset, so one shared instance serves it — which also keeps the prop's identity stable across renders instead of allocating per render.

Two decisions worth flagging

Scoped to the chat transcript. There are other scrollboxes — the prompt editor (multiline-input.tsx) and the landing screen. The editor is a few rows tall, where three lines a notch would skip most of its content, so it keeps the one-line default. A test pins that split so it isn't "fixed" later by accident.

Hardcoded, not configurable. The issue asks for 3 to match standard terminal and desktop behaviour, so that's what this does. Happy to put it behind a setting if you'd rather, but that seemed like unrequested surface area.

Verification

  • 4 new tests, confirmed red before the change (module didn't exist), green after.
  • Full suite: 39 failures, identical to the main baseline — no new ones.
  • tsc --noEmit clean on both touched files.
  • chat.tsx still fails prettier --check, but only at lines 279 and 931, both of which fail on unmodified main too. My lines (100 and 1668) are clean, so I've left it rather than bury the diff in an unrelated reformat.

One thing I could not verify locally: I checked the delta→multiplier→scrollTop path by reading OpenTUI's source rather than by driving a real wheel event, since onMouseEvent lives in the dependency. Worth a quick manual scroll on your side before porting.

Closes CodebuffAI#1268.

OpenTUI's ScrollBox multiplies each wheel event's notch delta by whatever
its ScrollAcceleration returns, and defaults to LinearScrollAccel, whose
tick() returns 1. A terminal reports one notch as a delta of 1, so the
transcript moves a single line per notch -- far slower than the three
lines terminals and desktop apps use.

ScrollBox already accepts a scrollAcceleration option, so this needs no
upstream change: the React reconciler spreads JSX props straight into the
renderable's constructor, which assigns the field the wheel handler reads.

Neither shipped accelerator gives a flat multiplier -- LinearScrollAccel
is fixed at 1, MacOSScrollAccel ramps with scroll velocity -- so this adds
a small stateless one. Being stateless, a single shared instance is enough,
which also keeps the prop's identity stable across renders.

Scoped to the chat transcript on purpose. The prompt editor's scrollbox is
a few rows tall, where three lines a notch would skip most of its content,
so it keeps the one-line default; a test pins that split.

Claude-Session: https://claude.ai/code/session_018vPhyqaaoKa8cgs7GEnyq5
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.

Feature Request: Increase mouse wheel scroll speed from 1 line to 3 lines

1 participant