event_loop: retry focus requests that land before the view is rebuilt
CI / build + test (push) Has been cancelled
CI / cargo audit (push) Has been cancelled

`take_focus_request()` looks up the target widget by `WidgetId` in `widget_rects`. Read-only `TextEdit` widgets are not tracked as interactive and therefore absent from `widget_rects`. A swipe-reveal flips the fields from read-only to interactive on `SlideRevealed`, but an intervening input event (e.g. the touch-up at the end of the swipe) can cause `dispatch()` to return before the vblank frame callback clears `frame_pending`, skipping the draw that would have rebuilt the widget tree. When the focus request fires in that same iteration it finds nothing and is consumed without effect.
`AppData` gains a `focus_retry` field. When `take_focus_request()` (or a previous retry) returns an id but the widget is not in `widget_rects`, the id is stored in `focus_retry`, `view_dirty` is set and a redraw is requested. The next time around the view has been rebuilt with interactive fields and the widget is present.
This commit is contained in:
2026-06-02 14:10:37 +02:00
parent e40ab637a6
commit ae8380b1ac
2 changed files with 10 additions and 1 deletions
+3
View File
@@ -248,6 +248,9 @@ pub struct AppData<A: App>
/// Set after the first commit of a rendered buffer on the main surface.
/// Used to drive `App::on_first_frame_committed` exactly once.
pub first_frame_committed: bool,
/// Focus request deferred because the target widget was absent from
/// `widget_rects` (e.g. read_only, not yet rebuilt). Retried next draw.
pub focus_retry: Option<crate::types::WidgetId>,
}
impl<A: App> AppData<A>