5e34dba2fda975996213a26c425e1aa411c8c322
Iris's 2026-09-08 report, both halves, and her own diagnosis of the second: "tapping outside of something that a fling is currently active for should have no code in common with the fling that could influence it." `run_sensors` runs a widget one frame after the pointer leaves it (`ActivationState::End`, which is not `Off`) so `HoverEnd` can fire, and `should_run` derived the press and wheel senses from raw button state without consulting `hover`. That farewell frame carried a `PressStart` to a widget the finger was nowhere near -- and a press on already-coasting content is a catch, which commits to a pan with no `DRAG_SLOP`, so the widget captured the pointer and swallowed the whole gesture. Its hover was stale because a gesture that ends while captured returns from the capture branch, which never reaches the loop that updates it. Measured before the fix on the real screen: a fence flicked sideways, then a finger down on a row 500px above it dragged 160px down the screen -- the list moved by zero, the fence moved by zero, and the fence held the pointer throughout. After: the list follows the finger and the fence's fling carries on coasting, which is what she asked for and falls out of the fix rather than being arranged. `should_run` now requires `hover.is_on()` for every non-hover sense. `Drop`/`Cancel` are unaffected -- they are delivered deliberately to a widget that is not under the pointer, with an explicit `On`. Also: the composer is clipped to its own bar rather than inside its padding (`.masked_by(rect(BAR_FILL))` in place of a `.masked()` + `.background()` pair) -- "the box should be clipped rather than the inset text". A long message was being sliced mid-glyph 12dp in from the bar's edge, leaving a band of bare surface above the cut. New: `Scroll::is_scrolling`, the name `List` already uses; the phone rig's `--message TEXT` and `--ime PX`, since the composer's overflowing and keyboard-open states cannot otherwise be looked at headlessly. Tests fail on the old code, one per layer: `a_press_does_not_reach_a_widget_the_pointer_has_just_left` (sensors, no screen) and `a_drag_away_from_a_coasting_fence_scrolls_the_list_and_ leaves_it_coasting` (the report itself, layer 1). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Languages
Rust
53%
Kotlin
44.4%
Shell
2.6%