28902ac83470c18e1515ea4a29e3443bcf844999
Reported: opening the keyboard lags more than it used to, and the scroll area lags behind the rest of the UI vertically until the keyboard is fully up. Both come from the shape of the previous commit's fix rather than from what it was fixing. Coercing the stuck-open animated inset to zero is right, but it was written as a bottom padding computed in `SessionScreen`'s body -- `padding(bottom = ... + imeInsets.getBottom(this).toDp())` -- and reading the inset there subscribes the whole composable to a value the platform rewrites every frame of the keyboard's animation. That is exactly what the comment above the box says the arrangement exists to avoid: the transcript box was meant to be the whole of what a keyboard frame re-measures, with nothing recomposed at all. Measured on the emulator with the debug button's counters, over one keyboard open on an idle session: `session screen recomposed` 16 before, 1 after -- the one being `isImeVisible` flipping, which is the recomposition the guard actually needs. The per-frame layout work either side is unchanged (17 measures of the transcript, ~0.6ms each), because that is the work the keyboard is supposed to cost. The second symptom is the same cause seen from the other end. The composer is moved by a `graphicsLayer` block, which re-reads the inset in the draw phase of the frame it changed; the transcript's padding was reading it in composition, so the two only stayed together while that recomposition kept landing inside the frame. `imePadding` reads it in the layout phase of the same frame, which is where it was before and where the composer can be followed from by construction. `isImeVisible` still does the correcting -- the modifier is dropped rather than the inset zeroed, which is the same coercion by a different route, so a callback starved of its `onEnd` still cannot leave the composer floating. Verified by tracking the two against each other frame by frame, from a screen recording rather than from uiautomator, whose bounds do not update per frame for a layer translation: the purple outline of the message field and the last message bubble both move -820px over the ~150ms the keyboard takes, and are within the 2px measurement floor of each other on every one of the ten frames in between. Format, compile and lint are clean.
Languages
Rust
53%
Kotlin
44.4%
Shell
2.6%