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

commit8d1f8b7426a8fbbb7b7d06afd64055d356fd795b
parentb4449d25c6
authorLucas Galante <[email protected]>
date2026-06-18 01:18
Fix spinbox right-click crash and Wayland popup sizing bugs

 src/backend/window_runner.rs      | 11 ++++++-----
 src/widget/input/dropdown.rs      |  3 +++
 src/widget/input/multi_control.rs |  3 +++
 src/widget/mod.rs                 |  3 +++
 4 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/src/backend/window_runner.rs b/src/backend/window_runner.rs
index 1fd2a40..491481e 100644
--- a/src/backend/window_runner.rs
+++ b/src/backend/window_runner.rs
@@ -1827,6 +1827,7 @@ impl<A: Application> PopupHandler for EngineState<A> {
                 popover.unfocus();
             }
         }
+        crate::widget::context_menu::hide();
         self.active_popup = None;
         self.redraw = true;
     }
@@ -2015,13 +2016,13 @@ pub fn run<A: Application>() {
             let (px, py, pw, ph, is_context_menu) = if !active_popovers.is_empty() {
                 let popover_widget = unsafe { &*active_popovers[0] };
                 let (x, y, w, h) = popover_widget.popover_rect().unwrap();
-                (x, y, w, h, false)
+                (x, y, w.max(1.0), h.max(1.0), false)
             } else {
                 (
                     crate::widget::context_menu::x(),
                     crate::widget::context_menu::y(),
-                    crate::widget::context_menu::w(),
-                    crate::widget::context_menu::h(),
+                    crate::widget::context_menu::w().max(1.0),
+                    crate::widget::context_menu::h().max(1.0),
                     true,
                 )
             };
@@ -2070,8 +2071,8 @@ pub fn run<A: Application>() {
                     
                     let scale_f32 = engine_state.scale_factor as f32;
                     let mut popup_config = main_config.clone();
-                    popup_config.width = (pw * scale_f32) as u32;
-                    popup_config.height = (ph * scale_f32) as u32;
+                    popup_config.width = ((pw * scale_f32) as u32).max(1);
+                    popup_config.height = ((ph * scale_f32) as u32).max(1);
                     wgpu_surface.configure(device, &popup_config);
                     
                     let cache = Cache::new(device);
diff --git a/src/widget/input/dropdown.rs b/src/widget/input/dropdown.rs
index 48f2e37..6678078 100644
--- a/src/widget/input/dropdown.rs
+++ b/src/widget/input/dropdown.rs
@@ -188,6 +188,9 @@ impl Element for Dropdown {
             return false;
         }
         let (x, y, w, h) = self.rect();
+        if w <= 0.0 || h <= 0.0 {
+            return false;
+        }
         let hx = if self.base.row_w > 0.0 { self.base.row_x } else { x };
         let hw = if self.base.row_w > 0.0 { self.base.row_w } else { w };
         if self.open {
diff --git a/src/widget/input/multi_control.rs b/src/widget/input/multi_control.rs
index 6af7b1a..bd42945 100644
--- a/src/widget/input/multi_control.rs
+++ b/src/widget/input/multi_control.rs
@@ -610,6 +610,9 @@ impl Element for MultiControl {
             }
         }
         let (x, y, w, h) = self.rect();
+        if w <= 0.0 || h <= 0.0 {
+            return false;
+        }
         px >= x && px <= x + w && py >= y && py <= y + h
     }
 
diff --git a/src/widget/mod.rs b/src/widget/mod.rs
index 1c0367c..2eaaba7 100644
--- a/src/widget/mod.rs
+++ b/src/widget/mod.rs
@@ -247,6 +247,9 @@ pub trait Element {
             return false;
         }
         let (x, y, w, h) = self.rect();
+        if w <= 0.0 || h <= 0.0 {
+            return false;
+        }
         let (hx, hw) = if let Some(b) = self.base() {
             if b.row_w > 0.0 {
                 (b.row_x, b.row_w)