git.lucas.co / cce-ui
GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git

commit518f2935eee9a393544bd96b133422ff403d2a03
parent99bae2cdfe
authorLucas Galante <[email protected]>
date2026-09-08 22:07
fix(focus): a widget parked off-screen is not a stop

Apps hide editors by parking them at (-1000, -1000) as 1x1 rects, still
"visible"; the walk wandered through eight invisible stops before reaching
the next real one. A rect ending at or before the origin cannot be seen, so
it is skipped.

Co-Authored-By: Claude Fable 5.1 <[email protected]>

 src/context.rs | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/src/context.rs b/src/context.rs
index b48e4a2..c913f64 100644
--- a/src/context.rs
+++ b/src/context.rs
@@ -591,6 +591,11 @@ impl UiContext {
             if width <= 0.0 || height <= 0.0 {
                 continue;
             }
+            // Parked off-screen (the hidden-editor idiom: a 1x1 rect at
+            // (-1000, -1000)) — nothing to see, so not a stop.
+            if x + width <= 0.0 || y + height <= 0.0 {
+                continue;
+            }
             found.push((y, y + height, x, id));
         }
         if found.is_empty() {
@@ -1262,5 +1267,16 @@ mod focus_step_tests {
         let mut sep = crate::widget::Separator::new(0.0, 0.0, 10.0, 1.0, [1.0; 4]);
         WidgetHost::set_rect(&mut sep, 300.0, 10.0, 10.0, 1.0);
         assert_eq!(WidgetHost::focus_role(&sep), crate::widget::FocusRole::None);
+
+        // A plate parked off-screen (the hidden-editor idiom) is not a stop either.
+        let mut parked = Button::new(0.0, 0.0, 1.0, 1.0).with_label("parked");
+        WidgetHost::set_rect(&mut parked, -1000.0, -1000.0, 1.0, 1.0);
+        let (pid, pptr) = (parked.base().id(), &mut parked as *mut dyn WidgetHost);
+        let pptr = unsafe { std::mem::transmute::<*mut dyn WidgetHost, *mut (dyn WidgetHost + 'static)>(pptr) };
+        ctx.register_widget(pid, pptr);
+        for _ in 0..4 {
+            ctx.focus_step(false);
+            assert!(!ctx.is_focused_id(pid), "the parked plate never takes focus");
+        }
     }
 }