Repository navigation
Conversation
The timeline only released its follow-the-end pin for a held pointer or a native touch scroll, and the custom scrollbar thumb stops its own pointer-down from reaching the timeline. Dragging the thumb up from the end therefore stayed pinned, and every size update scrolled the viewport back down. Autoscroll-style scrolling carries no pointer or wheel event at all, so it hit the same path. Decide from geometry instead of input devices: the distance to the end grows only when the view moves away from it, while a measurement adjustment moves the offset and the scroll range together and leaves it alone.
|
The following comment was made by an LLM, it may be inaccurate: |
There was a problem hiding this comment.
This fixes #56285. I ran the bot's reproduction in Chromium on the base and on this branch. On the base, dragging the scrollbar thumb snapped back to 0 px from the bottom on every frame, and autoscroll jumped back toward the bottom 8 times. With this change, autoscroll has no jumps and the thumb drag reaches the top and stays there. The new regression spec passes here and fails on the base. The full test:stability suite fails the same 12 tests with and without the change, so it shows no regression, though the follow-the-bottom and keyboard-scroll tests are among those 12. typecheck in packages/app is clean.
Public API is unchanged.
Using the change in scroll distance to decide when to stop following the bottom looks sound. Measurement adjustments move the scroll position and the scroll range together, so they don't release it. I have no blocking concerns.
Related: #55699
|
Thanks — the base-versus-branch reproduction is what I wanted checked, and your read of the geometry rule matches mine. On the twelve One environment prerequisite was in the way first: the stability config turns on video recording, and without the bundled |
|
Closing this to stay within GitHub's 3-open-pull-request limit for contributors without write access, which currently blocks every new pull request here. The branch remains on my fork, so I can reopen it on request. |
Issue for this PR
Closes #56285
Type of change
What does this PR do?
handleListScrollreleased the follow-the-end pin only for a held pointer or a native touch scroll, and every other upward scroll depended on an input handler to unpin first: the wheel handler for wheel, the touch handlers for touch. Two reported gestures produce neither. The custom scrollbar thumb callsstopPropagation()on its own pointer-down (packages/ui/src/components/scroll-view.tsx), so the timeline never records a held pointer andpointerHeldstays false for the whole drag. Autoscroll-style scrolling moves the offset with no pointer, wheel or key event at all. Both stayed pinned, so every size update while pinned scrolled the viewport back to the end on the next frame, which is the 1-frame oscillation in the report.The fix decides from geometry rather than from the input device. The distance to the end (
maxScroll - scrollTop) is what tells an arrival from a move away from it:So the unpin condition becomes "the distance to the end grew", and the previous pointer/touch clause stays as an additional way in, since content can shrink during a held drag. The pin path is unchanged: every
scrollToEnd()forcer is gated oninput.pinned(), so once the view is unpinned no size update can pull it back.I did not change the
arrivedheuristic or the paging thresholds. With the unpin in place the re-pin branch cannot run during a gesture, andonHistoryScrollis already called on every scroll event, so paging continues mid-gesture — the older-page loading in the report was reachable only after the view could stay away from the end at all. If a maintainer would rather see the pre-fetch threshold raised, that is a separate change.How did you verify your code works?
Added
packages/app/e2e/regression/timeline-scroll-unpin.spec.ts, two cases over an 80-exchange session opened at the end:.scroll-view__thumbto the top over 1 s and holds it, sampling the distance to the end every frame.Both assert the gesture reaches more than 200 px from the end, stays there, and never loses more than 50 px in a single frame.
Proof it is the change and not the harness — with only
virtualizer.tsxreverted and the spec unchanged:Both files pass
oxlint.bun run typecheckinpackages/appis clean;bun run typecheck:e2ereports only the four errors that are already ondev(performance/terminals/probe.ts,performance/timeline/session-timeline-stream-probe.ts,regression/timeline-stream.spec.ts), none in the new spec.Neighbouring timeline specs on the same build:
timeline-history,timeline-geometry,timeline-cache,session-panel-scrollbar,timeline-stream— 71 passed, 1 failed. The failure istimeline-cache.spec.ts"focuses Find in the selected cached timeline", which fails identically with the source reverted, so it predates this change.Screenshots / recordings
No screenshot: the change has no visual surface of its own.
Checklist
Added by the opencode bot (AI-generated).
Related: #55699