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

commit68ad8e20bba8132c865b1b483f287e5d43e89d41
parenteea3c3db96
authorLucas Galante <[email protected]>
date2026-06-18 02:20
Implement JsonLayoutWidget as_ptr_mut and add null target pointer safety checks for context menus

 src/context.rs            |  3 +++
 src/widget/core.rs        | 35 ++++++++++++++++++++---------------
 src/widget/json_layout.rs |  3 +++
 3 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/src/context.rs b/src/context.rs
index 476ca22..beb3fd4 100644
--- a/src/context.rs
+++ b/src/context.rs
@@ -347,6 +347,9 @@ impl UiContext {
     }
 
     pub fn handle_right_click(&mut self, target: *mut (dyn Element + 'static), px: f32, py: f32) {
+        if target.is_null() {
+            return;
+        }
         let name = unsafe { (*target).type_name() };
         let label = unsafe { (*target).label() };
         let header = if let Some(lbl) = label {
diff --git a/src/widget/core.rs b/src/widget/core.rs
index 2f71627..6eba037 100644
--- a/src/widget/core.rs
+++ b/src/widget/core.rs
@@ -474,6 +474,9 @@ pub mod context_menu {
         }
 
         pub fn show(&mut self, x: f32, y: f32, options: Vec<String>, target: *mut (dyn Element + 'static)) {
+            if target.is_null() {
+                return;
+            }
             self.x = x;
             self.y = y;
             self.options = options;
@@ -524,22 +527,24 @@ pub mod context_menu {
                     if idx > 0 {
                         let opt = self.options[idx].clone();
                         if let Some(target_ptr) = self.target {
-                            unsafe {
-                                let target = &mut *target_ptr;
-                                match opt.as_str() {
-                                    "Cut" => {
-                                        let _ = target.cut_selection();
-                                    }
-                                    "Copy" => {
-                                        target.copy_selection();
-                                    }
-                                    "Paste" => {
-                                        let _ = target.paste_from_clipboard();
-                                    }
-                                    "Select All" => {
-                                        target.select_all();
+                            if !target_ptr.is_null() {
+                                unsafe {
+                                    let target = &mut *target_ptr;
+                                    match opt.as_str() {
+                                        "Cut" => {
+                                            let _ = target.cut_selection();
+                                        }
+                                        "Copy" => {
+                                            target.copy_selection();
+                                        }
+                                        "Paste" => {
+                                            let _ = target.paste_from_clipboard();
+                                        }
+                                        "Select All" => {
+                                            target.select_all();
+                                        }
+                                        _ => {}
                                     }
-                                    _ => {}
                                 }
                             }
                         }
diff --git a/src/widget/json_layout.rs b/src/widget/json_layout.rs
index f30b49f..a5b9477 100644
--- a/src/widget/json_layout.rs
+++ b/src/widget/json_layout.rs
@@ -280,6 +280,9 @@ impl Element for JsonLayoutWidget {
     fn as_ptr(&self) -> *mut (dyn Element + 'static) {
         self as *const Self as *mut Self as *mut (dyn Element + 'static)
     }
+    fn as_ptr_mut(&mut self) -> *mut (dyn Element + 'static) {
+        self as *mut Self as *mut (dyn Element + 'static)
+    }
 
     fn base(&self) -> Option<&Widget> { Some(&self.base) }
     fn base_mut(&mut self) -> Option<&mut Widget> { Some(&mut self.base) }