Merge remote-tracking branch 'origin/rustify' into worktree-agent-a1ff0294b6c29127e

# Conflicts:
#	docs/RUST.md
This commit is contained in:
iris committed 2026-09-06 00:54:06 -04:00
commit c589a75fa0
6 files changed
+814 -26

No files matched your search

+31
View File
@@ -8,6 +8,37 @@ capability that moved. Small and trivial changes do not go here.
An entry gives the date, what changed, why, and a short before/after where
it helps judge the change without the session that made it. Newest first.
## 2026-09-06: `List::fling`, `VelocityTracker`, `FlingCalculator` (IRIS_TODO.md's "swiping has no momentum")
`iris::widget::List` gained a real fling: `fling(velocity_px_per_s)` starts
one (cancelled by the next touch-down via `cancel_fling`, or automatically
once it settles or reaches loaded content's start/end), `is_scrolling()`
reports whether one is running, and `tick_fling(now: Instant) -> bool`
advances it and returns whether it is still going -- a caller that owns a
`RequestRedraw` handle can hand it to the list once via the new
`set_redraw_handle`, after which `List` re-arms its own next frame while
flinging with no further polling needed; a caller driving a scripted
benchmark instead calls `tick_fling` itself in a loop, same as it already
drives `scroll`.
The physics is `iris::sense::FlingCalculator` + `VelocityTracker`
(`sense.rs`, beside `DragArbiter`): a port of AOSP `SplineOverScroller`'s
deceleration curve (the same one Compose's own `ScrollableDefaults.
flingBehavior()` uses), cited at the definition, so a fling here travels
the same distance a Compose `LazyColumn` would for the same initial
velocity. `VelocityTracker` estimates that velocity from the drag's last
~100ms of samples rather than one frame's last delta. Unit-tested:
velocity from known samples, fling distance/duration against the closed-
form spline result (within 1%), cancel-on-touch, and the start/end clamp
(a fling stops rather than scrolling into content that was never loaded).
Before: a touch-drag panned exactly as far as the finger moved and stopped
dead on release. After: releasing mid-drag continues scrolling and
decelerates, matching the muscle memory every other Android scroll view
already trained. `transcript_ui::selection::Selection::drag` wires this in
-- a release only flings if the gesture had committed to panning
(`DragArbiter::is_panning`, new), never a selection or an undecided tap.
## 2026-09-06: `UiRenderNode::new` returns `Result`, not `Self` (RUST.md's P0 box, phone-crash fix)
`iris_core::UiRenderNode::new(device, queue, config)` now returns
+25 -14
View File
@@ -124,20 +124,31 @@ follow-ups. Recorded here rather than fixed in that pass, so a follow-up
agent takes them without colliding with that pass's `bench_client.rs`/
`android/view.rs`/`android/sense.rs` changes.
- [ ] **Swiping has no momentum.** iris's `List` pans exactly as far as the
finger moves and stops dead on release -- unlike Compose, which flings
and decelerates. Needs velocity tracking over the last several move
samples and an Android-style decelerating fling, cancelled by the next
touch-down, redrawing every frame until it settles. `BenchRun.kt`'s own
fling phase (RUST.md's "Benchmark v2" box) is the reference shape:
"travel way faster... which is better for stress testing."
- [ ] **Scrolling down sometimes jitters the text.** Two named suspects,
neither confirmed: `DragArbiter`'s slop being released as one jump
(`iris/src/sense.rs`), or a per-frame pan delta applied a frame late.
Measure by tracing the list's scroll offset per frame against a
monotonic synthetic drag, the same way `iris/android-app/trace-draw.sh`-
style instrumentation traced the touch-scroll dropout in RUST.md's I5
box -- not by eyeballing a screenshot.
- [x] **Swiping has no momentum, fixed 2026-09-06.** `List::fling`/
`VelocityTracker`/`FlingCalculator` (`iris/src/widget/list.rs`,
`iris/src/sense.rs`) -- IRIS.md's 2026-09-06 entry has the full account.
Wired through `Selection::drag`'s release path, cancelled by the next
touch-down, clamped at the loaded content's start/end. Verified by unit
test (fling distance against the closed-form spline result, cancel-on-
touch, the clamp), not yet by an on-device or emulator feel-check --
that is still open.
- [x] **Scrolling down sometimes jitters the text, fixed 2026-09-06.**
Root-caused by reading `DragArbiter::update`'s `Undecided`-to-`Panning`
transition rather than by an on-device trace (no emulator was used this
pass): it was the first named suspect, not the second. `self.last` stays
at the press origin for every `Undecided` frame (nothing pans while the
gesture might still be a selection), so the frame that finally crosses
`DRAG_SLOP` returned `Pan(dy)` with `dy` measured from `press_start` --
the *whole* pre-threshold drag, applied to the list in one step, however
many frames it had taken to get there. Fixed by applying only the
excess past `DRAG_SLOP` on that one frame (`dy - DRAG_SLOP.copysign
(dy)`), the same "consume the slop, don't replay it" rule Android's own
touch handling follows. New regression test,
`crossing_the_slop_by_a_little_pans_by_a_little` (`iris/src/sense.rs`).
**Not yet done**: an emulator trace of the real per-frame offset
confirming this was the whole story on real touch input rather than
only the arbiter's own unit tests -- worth a follow-up pass before
calling it fully closed.
## Build
+20
View File
@@ -4561,6 +4561,26 @@ device.
two-density crispness check IRIS_TODO.md's unit item asks for, and
the two open items just above.
**Fling and jitter, 2026-09-06.** The two `IRIS_TODO.md` "From the
phone" items this box's own text names as follow-ups are fixed --
`List::fling`/`VelocityTracker`/`FlingCalculator` (IRIS.md's
2026-09-06 entry) and the `DragArbiter` slop-release jump (fixed by
applying only the excess past `DRAG_SLOP` on the crossing frame,
not the whole pre-threshold drag) -- both wired through
`Selection::drag`'s release path, both covered by new unit tests in
`iris/src/sense.rs` and `iris/src/widget/list.rs`. **Root-caused by
reading `DragArbiter::update` and testing it directly, not by an
emulator trace** -- this pass did not open an emulator, so the
"trace the list's offset per frame" verification this box's own
todo asked for is still open, as is a feel-check of the fling on
real touch input. **Benchmark v2's four-phase spec (fling/stream/
type/keyboard) in `bench_client.rs` was not attempted this pass** --
wiring a real IME show/hide and refresh-rate read through
`bench_jni.rs`, and `FrameReport`'s per-phase accounting, is real
scope on its own and was left rather than shipped half-verified;
the Compose half above is already done and is the reference shape
for whoever picks this up. No redelivery this pass.
- [ ] **P1 — session screen parity.** History paging backward (with the
page-boundary healing `client-core` does not have yet, below),
`TranscriptSource`-backed cache/server stitching, jump-to-latest,