iris: DragArbiter closes I5's touch-drag pan-vs-select gap
A row's own click_or_drag() selection handler always won the same gesture a list-level pan wanted, since run_sensors gives the inner layer first refusal every frame it's pressed. DragArbiter (iris/src/sense.rs) decides pan vs. select the way Android does: vertical drag pans immediately, a held stationary press starts a selection after LONG_PRESS, and a horizontal drag on already-selected text extends immediately. transcript-ui's Selection::drag routes every row's drag through one arbiter per list, driving List::scroll for a pan instead of a second scroll mechanism. 8 new unit tests (iris::sense::drag_arbiter_tests); cargo fmt/clippy/test --workspace and cargo ndk (iris, transcript-ui) all clean; run-headless.sh screenshot byte-identical to before the change. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
a853eb5a4d
commit
e5880c33f4
7 files changed
+486
-79
No files matched your search
+19
-11
@@ -184,17 +184,25 @@ order and what "done" looks like. Tick and date them in place.
|
||||
`app/ui-sandbox.sh --delay` (this crate deliberately fetches nothing
|
||||
itself, `transcript-ui/src/lib.rs`'s doc), a new cdylib + Gradle
|
||||
module, then the bench script pointed at it.
|
||||
- [ ] **Touch-drag panning over a row's own rendered text.** `row.rs`
|
||||
registers `CursorSense::click_or_drag()` on each row's `TextEdit` for
|
||||
cross-row selection; `TextEdit::draw`'s `painter.child_layer()`
|
||||
(`iris/src/widget/text/edit.rs:87`) means that registration wins
|
||||
`core/src/sense.rs::run_sensors`'s per-layer arbitration on every
|
||||
frame it is pressed, not just the frame the press started, so a list
|
||||
pan gesture registered on `List` itself never gets a turn while a
|
||||
row is under the finger. Fix: a small press distance/time arbiter
|
||||
deciding pan vs. select before either commits, or gate text-drag-
|
||||
selection behind a long-press so an ordinary swipe always pans first.
|
||||
`lib.rs`'s module doc has the full diagnosis.
|
||||
- [x] **Touch-drag panning over a row's own rendered text — done,
|
||||
2026-09-05.** `row.rs` used to register `CursorSense::click_or_drag()`
|
||||
on each row's `TextEdit` for cross-row selection; `TextEdit::draw`'s
|
||||
`painter.child_layer()` (`iris/src/widget/text/edit.rs:87`) meant that
|
||||
registration won `core/src/sense.rs::run_sensors`'s per-layer
|
||||
arbitration on every frame it was pressed, not just the frame the
|
||||
press started, so a list pan gesture registered on `List` itself never
|
||||
got a turn while a row was under the finger. Fixed with
|
||||
`iris::sense::DragArbiter` (recorded in `IRIS.md`), one small state
|
||||
machine per list deciding pan vs. select the way Android does (a
|
||||
vertical drag pans immediately; a stationary press held `LONG_PRESS`
|
||||
(500ms) starts a selection which further drag extends; a horizontal
|
||||
drag while something is already selected extends immediately) —
|
||||
`transcript-ui/src/selection.rs`'s `Selection::drag` is the one place
|
||||
every row's drag now routes through. 8 new unit tests
|
||||
(`iris/src/sense.rs`'s `drag_arbiter_tests`); `cargo fmt/clippy/test
|
||||
--workspace` and `cargo ndk` (both `iris` and `transcript-ui`) all
|
||||
clean; `run-headless.sh` screenshot byte-identical to before the
|
||||
change (38578 bytes). See RUST.md's I5 box, "Gap closed, 2026-09-05".
|
||||
- [ ] **Row-level accessibility names.** The composer carries
|
||||
`.label("Message")`; transcript rows do not carry a `.label()` of
|
||||
their own yet, so `Widgets::named()` (I4) does not include them —
|
||||
|
||||
Reference in new issue
Block a user