From 3998710cdc10210af307e05456dffb52122b279f Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Sun, 12 Apr 2026 17:10:12 +0200 Subject: [PATCH] destroy boxed window data when a window is destroyed --- ui-rs/src/ui/ffi.rs | 1 + ui-rs/src/ui/window.rs | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ui-rs/src/ui/ffi.rs b/ui-rs/src/ui/ffi.rs index 55d8b9b..8e2da06 100644 --- a/ui-rs/src/ui/ffi.rs +++ b/ui-rs/src/ui/ffi.rs @@ -48,6 +48,7 @@ pub struct UiList { } pub type UiCallback = Option; +pub type UiDestructor = extern "C" fn(object: *mut c_void); #[repr(C)] diff --git a/ui-rs/src/ui/window.rs b/ui-rs/src/ui/window.rs index ec01779..6be3ff1 100644 --- a/ui-rs/src/ui/window.rs +++ b/ui-rs/src/ui/window.rs @@ -5,7 +5,7 @@ use std::ffi::{c_char, c_int, c_void}; use std::ffi::CString; use std::marker::PhantomData; use crate::ui::toolkit; -use crate::ui::ffi::UiObject; +use crate::ui::ffi::{UiContext, UiDestructor, UiObject}; extern "C" { fn ui_window(title: *const c_char) -> *mut UiObject; @@ -18,8 +18,13 @@ extern "C" { fn ui_object_get_windowdata(obj: *const UiObject) -> *mut c_void; fn ui_object_set_windowdata(obj: *mut UiObject, data: *mut c_void); + fn ui_object_get_context(obj: *const UiObject) -> *mut UiContext; + + fn ui_reg_destructor(ctx: *mut UiContext, data: *mut c_void, destructor: UiDestructor); } + + impl toolkit::UiObject { pub fn show(&self) { unsafe { @@ -59,10 +64,21 @@ where F: FnOnce(&mut toolkit::UiObject, &mut T) { let wdata_ptr = Box::into_raw(window_data); unsafe { ui_object_set_windowdata(objptr, wdata_ptr as *mut c_void); + let ctx = ui_object_get_context(objptr); + ui_reg_destructor(ctx, wdata_ptr as *mut c_void, destroy_boxed::); } obj } +extern "C" fn destroy_boxed(data: *mut c_void) { + if data.is_null() { + return; + } + unsafe { + drop(Box::from_raw(data as *mut T)); + } +} + pub fn window(title: &str, data: T, create_ui: F) -> toolkit::UiObject where F: FnOnce(&mut toolkit::UiObject, &mut T) { -- 2.47.3