From 96f437544a2a9a0418cd95223cb02f6f8195e55e Mon Sep 17 00:00:00 2001 From: "Pedro M. de Echanove Pasquin" Date: Wed, 13 May 2026 13:47:01 +0200 Subject: [PATCH] =?UTF-8?q?event=5Floop:=20route=20`take=5Ffocus=5Frequest?= =?UTF-8?q?`=20to=20widgets=20on=20overlay=20surfaces=20The=20`take=5Ffocu?= =?UTF-8?q?s=5Frequest`=20block=20in=20`try=5Frun`=20only=20searched=20`da?= =?UTF-8?q?ta.main.widget=5Frects`=20for=20the=20requested=20`WidgetId`,?= =?UTF-8?q?=20so=20an=20app=20that=20wanted=20to=20focus=20a=20widget=20li?= =?UTF-8?q?ving=20on=20an=20overlay=20surface=20(a=20search=20field=20on?= =?UTF-8?q?=20a=20launcher=20overlay,=20a=20text=20edit=20on=20a=20dialog?= =?UTF-8?q?=20modal,=20a=20password=20field=20on=20a=20popup)=20silently?= =?UTF-8?q?=20no-op'd:=20the=20widget=20existed=20and=20had=20been=20laid?= =?UTF-8?q?=20out,=20but=20the=20lookup=20never=20found=20it=20because=20i?= =?UTF-8?q?t=20was=20scanning=20the=20wrong=20`widget=5Frects`.=20Crustace?= =?UTF-8?q?=20hit=20this=20trying=20to=20put=20cursor=20focus=20on=20the?= =?UTF-8?q?=20launcher=20search=20field=20when=20the=20launcher=20slides?= =?UTF-8?q?=20up=20=E2=80=94=20the=20field=20rendered=20with=20a=20visible?= =?UTF-8?q?=20caret=20but=20typing=20went=20to=20whoever=20the=20keyboard?= =?UTF-8?q?=20had=20been=20focused=20on=20before.=20The=20lookup=20now=20f?= =?UTF-8?q?alls=20through=20to=20`data.overlays.iter()`=20if=20the=20main?= =?UTF-8?q?=20scan=20misses,=20returning=20the=20first=20`(SurfaceFocus::O?= =?UTF-8?q?verlay(id),=20flat=5Fidx)`=20whose=20surface=20carries=20a=20wi?= =?UTF-8?q?dget=20with=20that=20id.=20`data.set=5Ffocus`=20already=20accep?= =?UTF-8?q?ts=20the=20`SurfaceFocus`=20discriminant,=20so=20the=20call=20s?= =?UTF-8?q?ite=20just=20forwards=20what=20the=20lookup=20found=20and=20req?= =?UTF-8?q?uests=20a=20redraw=20on=20the=20matching=20surface=20instead=20?= =?UTF-8?q?of=20unconditionally=20on=20main.=20No=20effect=20on=20apps=20t?= =?UTF-8?q?hat=20target=20main-surface=20widgets=20=E2=80=94=20the=20main?= =?UTF-8?q?=20scan=20still=20runs=20first=20and=20short-circuits=20the=20o?= =?UTF-8?q?verlay=20walk.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/event_loop/mod.rs | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/event_loop/mod.rs b/src/event_loop/mod.rs index e086efd..2ccea1c 100644 --- a/src/event_loop/mod.rs +++ b/src/event_loop/mod.rs @@ -497,17 +497,41 @@ pub( crate ) fn try_run( app: A ) -> Result<(), RunError> draw_frame( &mut data ); } - // Focus the widget with the requested WidgetId if the app requests it + // Focus the widget with the requested WidgetId if the app requests it. + // Walks main + every overlay because the targeted widget can live + // on any of them (a search field on a launcher overlay, a text + // edit on a dialog modal, …). if let Some( id ) = data.app.take_focus_request() { - let found = data.main.widget_rects.iter() + let mut hit: Option<( SurfaceFocus, usize )> = data.main.widget_rects.iter() .find( |w| w.id == Some( id ) ) - .map( |w| w.flat_idx ); - if let Some( flat_idx ) = found + .map( |w| ( SurfaceFocus::Main, w.flat_idx ) ); + if hit.is_none() + { + for ( ov_id, surf ) in &data.overlays + { + if let Some( w ) = surf.widget_rects.iter().find( |w| w.id == Some( id ) ) + { + hit = Some( ( SurfaceFocus::Overlay( *ov_id ), w.flat_idx ) ); + break; + } + } + } + if let Some( ( focus, flat_idx ) ) = hit { let qh = data.qh.clone(); - data.set_focus( SurfaceFocus::Main, Some( flat_idx ), &qh ); - data.main.request_redraw(); + data.set_focus( focus, Some( flat_idx ), &qh ); + match focus + { + SurfaceFocus::Main => data.main.request_redraw(), + SurfaceFocus::Overlay( id ) => + { + if let Some( s ) = data.overlays.get_mut( &id ) + { + s.request_redraw(); + } + } + } } } }