Files
ai-app/app/androidApp
irisandClaude Opus 5 0a0949ee7f Search the row tops, tell the truth about the window, report the residual
Three things, and the middle one is why the last commit's "zero flickers"
was worth nothing.

**The detector was measuring the wrong thing.** `covered()` compared what
is on screen against `retained` -- which is the *intent*. Those came apart
the moment the window started being recomputed during layout, because it is
then updated before the frame draws: the check passed while the screen was
still showing the spacers from the composition before. It now compares
against what the list actually composed, recorded as it composes it. The
first honest run found the open path still failing, and the counters named
a branch of my own that did nothing at all -- position lost, scroll
container reporting a measured position from a *different* session, so
neither arm ran and the window was left empty. The whole transcript then
composed as a single spacer. The test is no longer "is there a position to
trust" but "is the window empty", which is the question that was actually
being asked.

**The scan was the lag.** Putting the recompute where the layout is made it
correct and put a linear pass over every row into every frame with it --
0.5ms to 1.1ms of placement at 190 rows, the same O(rows)-per-frame mistake
this file exists to undo, reintroduced by its own fix. The tops are
ascending by construction, so it is a binary search.

**The button now does the subtraction.** The draw phase carries Compose's
measurement as well as its recording, so "draw is high" never said which of
three things was high, and the split was being worked out by hand in a
conversation every time a report arrived. It reports the per-frame split
directly: the transcript's own measure, placement and recording, and what
is left, which is the framework's bookkeeping after a layout.

The immediate window went from two screens to three, and from six rows to
twelve. What the list has composed is always one frame behind what the
window says -- the window is recomputed in layout and the rows it names are
built by the next composition -- so the margin has to cover a frame of
movement as well as the gap between recomputations. Measured down from
misses of one and two rows.

Verified: three cycles of open, fling up through a page load, fling back,
close, on a 92-row session, plus reopens of a short one. Zero, with the
detector that no longer flatters itself.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 13:59:19 -04:00
..