docs: phone report 2026-09-07 later -- overscroll, low initial fling velocity, input/timing report; queued

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Fable 5.1 committed 2026-09-07 16:04:34 -04:00
1 parent 5be9f1baac
commit 9ed01e2812
2 files changed
+45

No files matched your search

+40
View File
@@ -955,3 +955,43 @@ do not duplicate it there.
the header's bottom must be masked. Fix both with one rule: a row is the header's bottom must be masked. Fix both with one rule: a row is
drawn if any part of it intersects the viewport, and the viewport is drawn if any part of it intersects the viewport, and the viewport is
the list's own region. the list's own region.
## From the phone, 2026-09-07, later (build from 4274b8b, ai-app-bench b47eb73)
- [ ] **"You shouldn't be able to scroll below the bottom (or above
top)."** The list's offset is not clamped to its content range while
dragging and/or flinging. Compose's `LazyColumn` never moves content
past its ends -- the overscroll *effect* on Android 12+ is a stretch
drawn over clamped content, not a displacement. Clamp the offset in
one place (`List`'s scroll setter, so drag, fling, page-in and
programmatic scroll all go through it) and end a fling that hits the
clamp. Test at layer 1: a drag past either end leaves the offset at
the end; a fling into the end stops there.
- [ ] **"Flinging now actually works but is slower than Compose's
immediately after releasing the flick (the slow down seems
correct)."** The curve is right, so the *initial velocity* is low.
iris's `VelocityTracker::velocity` is total motion over the window's
span -- an average -- where Compose's `VelocityTracker` (`compose.ui`
`VelocityTracker.kt`, `VelocityTracker1D` with `Strategy.Impulse`,
100ms horizon, 20 samples, `AssumePointerMoveStoppedMilliseconds =
40`) weights the last samples, so a flick that accelerates into the
release reads faster. Port the impulse strategy from source with
checked-in reference values from an independent transcription, as
the spline was; also apply Compose's min/max fling velocity
(`ViewConfiguration`'s 50dp/s and 8000dp/s) so a slow release does
not fling and a wild one is capped. Layer-1 test on
`flick-120hz.touch` asserting the number Compose's code gives.
- [ ] **Input-event and timing report from the phone.** Iris: "add
another button to copy input event info so that I can do some stuff
manually and then send the event log to you ... instrument a lot of
the code with timings so I can give you time reports through the
same button." Build on the log ring (queue: logging through Dev
Updater), not beside it: every `MotionEvent` (action, pointer
position, event time, historical sample count) and every gesture
decision (`iris drag release:` and its siblings) at debug level into
the ring; frame timings (input handled -> layout -> draw submitted,
and the fling tick's `now` against the frame clock) at debug level
into the same ring; "Copy report" already appends the ring. Add a
second button only if the report gets too long to paste -- then
"Copy input log" copies the ring alone. Says which build it came
from.
+5
View File
@@ -240,6 +240,11 @@ closes it.
rest of her phone shows (UI_RULES "show what the reader already sees rest of her phone shows (UI_RULES "show what the reader already sees
elsewhere"), at the cost of the app no longer looking identical on elsewhere"), at the cost of the app no longer looking identical on
every device. Not done without her verdict. every device. Not done without her verdict.
- [ ] Scroll clamped at both ends, and Compose's impulse velocity
estimator with min/max fling velocity (docs/IRIS_TODO.md, 2026-09-07
later). After the culling fix lands (same file).
- [ ] Input-event and timing instrumentation into the log ring, copied
by the report button. After the logging route lands (same ring).
- [ ] Masks with a shape -- docs/LAYOUT.md "Masks with a shape (decided - [ ] Masks with a shape -- docs/LAYOUT.md "Masks with a shape (decided
2026-09-07)". A mask references a primitive already drawn 2026-09-07)". A mask references a primitive already drawn
(rect SDF, texture or glyph alpha), chained and multiplied; `.masked()` (rect SDF, texture or glyph alpha), chained and multiplied; `.masked()`