text_selection: drag-autoscroll never moved a virtualized list - #2948
text_selection: drag-autoscroll never moved a virtualized list#2948kossoy wants to merge 1 commit into
Conversation
|
Thanks for chasing this down — the symptom you instrumented (726 deltas dispatched, The synthetic wheel does move a virtualized listThe repo already has
The reason is that gpui's So the participant notification is not replacing a dead path — it is running alongside a live one. Consequence: two timers drive the same listAfter this change a scrollable
Autoscroll therefore runs at roughly double its previous speed (the table above), and because one writer is relative-from-now and the other absolute-from-last-frame, they race across repaints: when the participant timer ticks twice between paints, the wheel's stale base snaps the list backwards. That is visible jitter, not just a speed change. The dispatch needs to be exclusive — notify the participant or send the wheel. The natural seam is the The delta uses the wrong rectangle for a self-scrolling participant
Concretely, a scrollable The participant notification should use Smaller things
On the original symptomNone of this explains your field repro, and I'd rather not see it papered over. The wheel path works in the harness, so something in your layout keeps the list's hitbox out of the hit-test set at the clamped synthetic position — another hitbox painted above it, or the list not present in the frame being hit-tested. Worth identifying before locking in a fix, since the exclusive-dispatch design above depends on knowing which participants can rely on the wheel at all. One note for whoever lands this: the test at 🤖 Review assisted by Claude Code |
update_auto_scrollnotifies the participant — which scrolls itself through itsown list API — only on the branch taken when no
Windowis available:A live drag always passes
Some(window), so the only branch a drag ever tookwas the synthetic-wheel one, and a synthetic
ScrollWheelEventnever reaches avirtualized list's scroll handler while the pointer is captured by the drag. The
working branch was dead code for the one flow that matters. Autoscroll computed
and dispatched a correct delta forever while the list stood still.
Reproduction
Open a long document in a scrollable
TextView. Anchor a selection near the topof the viewport, drag to the bottom edge and hold with small movements for
several seconds.
Instrumented: 726 events with
delta = Some(16.33 px)dispatched,px_offstays
0.0, selection captures only the visible viewport (≈ 2 KB of a 132 KBnote).
Fix
Notify the participant unconditionally, then keep the wheel dispatch for
participants that scroll through an ancestor container rather than a list of
their own — for a participant that handled the notification the wheel is a
no-op.
After: the same 8-second hold scrolls
px_off 0 → 5 382.8and the selectionextends to 38 KB.
crates/base/src/text_selection.rs, +14 lines, no gpui corechange.