Skip to content

Transcript: wheel direction decides tail-follow - #794

Open
RemingtonWilcox wants to merge 1 commit into
zeronsh:mainfrom
RemingtonWilcox:transcript-wheel-follow
Open

RemingtonWilcox wants to merge 1 commit into
zeronsh:mainfrom
RemingtonWilcox:transcript-wheel-follow

Conversation

@RemingtonWilcox

@RemingtonWilcox RemingtonWilcox commented Oct 4, 2026 •

Copy link
Copy Markdown

Summary

  • While a reply streams, a wheel-down could break tail-follow, and getting it back sometimes needed the very last pixel. Pin decisions compared the distance from the bottom with last_scroll_distance, which can lag streaming growth by a layout, so growth looked like the user scrolling away.
  • The transcript root now records each wheel event's vertical delta (wheel_dy). The scroll handler decides from its sign: wheel up breaks the pin, wheel down inside the 70px band re-sticks, and reaching the bottom still re-sticks as before.
  • This matches gpui's own list, which stops following its tail on delta.y > 0.
  • should_restick takes the wheel delta instead of the previous distance. The own-turn branch uses it too, so both branches follow one rule.

Worth a close look

  • The direction comes from a root on_scroll_wheel listener. The list's wheel handler runs before it, and handle_scroll reads wheel_dy in its deferred half, so the value is set before it is read. The list calls the scroll handler only from wheel/touch input (ListState::scroll is reached only from its ScrollWheelEvent listener), so every read follows a fresh write.
  • A horizontal-only swipe has dy == 0. It neither breaks nor re-sticks the pin; only landing at the bottom (≤ 2px) re-sticks.
  • Left out: the jump pill's scroll_anim = None (a rail glide fighting the bottom spring) and skipping the prompt re-hold when the prompt row is gone. Both looked real, but neither has a failing test yet, so they can be separate PRs.
  • In the recording, when following resumes the view can sit about 40 px above the true bottom rather than snapping flush.

Test plan

  • New wheel_direction_not_a_stale_distance_decides_the_pin (Linux headless window test): pinned with a stale distance baseline, wheel down keeps the pin and wheel up breaks it.
  • restick_is_direction_aware updated to the delta signature; passes.
  • cargo test -p zeron-ui --lib on Windows: 1481 passed, 0 failed.
  • The new window test only builds on Linux (like its user_fold_scroll siblings) and was NOT run locally. It compiles, but Windows' headless platform can't open the window. CI's Linux UI job is the first run, so its fail-without-fix also hasn't been checked yet.
  • Manual check in the app: not done yet.
  • Linux UI and core suites on the fork's CI (ui-tests workflow): https://github.com/RemingtonWilcox/zeron/actions/runs/37240660629

Screenshots

Dark, about 15 s, mock harness streaming a long reply. The view follows the tail. One wheel notch up stops following while text keeps arriving below. One notch down lands inside the bottom band and following resumes without reaching the last pixel.

Recording: wheel up stops tail-follow, wheel down into the bottom band resumes it

MP4 of the same clip: https://gist.githubusercontent.com/RemingtonWilcox/7274b28983e89f6b18cbb0b64a205134/raw/a266fbc0f006d297541e92fe7584b124e7ab567b/wheel-follow-dark.mp4

Not captured: the same steps on main.

🤖 Generated with Claude Code

Pin decisions compared the distance from the bottom with the distance at
the last observation. While a reply streams, that baseline can predate the
latest growth by a layout, so a wheel-down mid-stream read as scrolling
away and broke the pin, and re-sticking needed the very last pixel. The
root now records each wheel event's vertical delta, and the scroll handler
(only ever called from wheel input) decides by its sign: up breaks the pin,
down inside the 70px band re-sticks. This is the same rule gpui's list uses
to stop following its tail (delta.y > 0).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@RemingtonWilcox
RemingtonWilcox marked this pull request as ready for review October 4, 2026 23:29
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.

1 participant