iris: generalize drag arbitration into a default-input DragGesture, with pointer capture and Drop
Iris asked (2026-09-06) that dragging be part of iris's default input system rather than duplicated per app: "anything that provides good performance and can be generalized well is part of iris rather than the app." DragArbiter and VelocityTracker (both already in iris::sense) are now bundled into a new DragGesture, which also takes exclusive pointer capture (UiRenderState::capture_pointer/release_pointer/captured_pointer) the moment a gesture commits to panning or selecting, and delivers a new CursorSense::Drop -- not PressEnd -- to the captured widget when the button lifts, wherever on screen that happens to be. This directly targets the phone bench's "finger flings do nothing": per-widget hit testing silently drops a gesture the instant the pointer moves off every registered region, which a fast pan/fling does routinely (crossing several virtualised rows, or ending off the loaded content entirely) -- so PressEnd, and the velocity/fling-start decision hanging off it, was frequently never delivered at all. Capture targets List's own stable id (List::key_at resolves the row-under-pointer from its extents), not a row's, since List retires rows mid-drag as content scrolls. transcript-ui::Selection::drag now only decides pan-vs-select from DragGesture's outcome; row.rs's per-row registration is only ever a gesture's first frame, with lib.rs registering the List-level continuation once. New tests: sense_tests.rs's two pointer-capture regressions, list.rs's replacing_the_last_row_many_times_does_not_leak_primitives (a P0 stale-primitives diagnostic -- passes, pinning the widget-arena layer as not the leak). MainActivity.java opts into edge-to-edge (Window::setDecorFitsSystemWindows(false), API 30+, no new dependency) so window insets are redelivered on every change including a pure IME toggle -- the named-but-untried fix for the phone bench's "keyboard: could not be shown" and the emulator's identical non-confirmation. cargo fmt/clippy/test clean across the iris workspace. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
71a3fae655
commit
e12c708246
8 files changed
+571
-86
No files matched your search
@@ -31,6 +31,25 @@ public final class MainActivity extends Activity {
|
||||
setContentView(layout);
|
||||
view.requestFocus();
|
||||
|
||||
// RUST.md's P0 box, defect 4 ("keyboard: could not be shown"):
|
||||
// `logcat` showed the platform's own IME open/resize happening
|
||||
// while `setOnApplyWindowInsetsListener` fired only once, at
|
||||
// attach, and never again for a pure keyboard toggle -- a plain
|
||||
// (non-edge-to-edge) window is only guaranteed that one initial
|
||||
// dispatch; `adjustResize` handling the IME entirely by resizing
|
||||
// the window is not itself a trigger for a fresh one. Opting into
|
||||
// edge-to-edge (a platform call, API 30+, no new dependency) is
|
||||
// what makes the system redeliver insets on every change,
|
||||
// including the ones this activity actually cares about --
|
||||
// `getSystemWindowInset*` below is unaffected by this (it has
|
||||
// always reported the raw system-bar/IME overlap regardless of
|
||||
// who consumes it), so the on-screen bars and the padding Rust
|
||||
// already derives from those four numbers are unchanged; only the
|
||||
// callback's firing became reliable.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
getWindow().setDecorFitsSystemWindows(false);
|
||||
}
|
||||
|
||||
view.setOnApplyWindowInsetsListener((v, insets) -> {
|
||||
int left = insets.getSystemWindowInsetLeft();
|
||||
int top = insets.getSystemWindowInsetTop();
|
||||
|
||||
Reference in new issue
Block a user