git.lucas.co / cce-color-editor
color picker and palette editor
git clone https://git.lucas.co/cce-color-editor.git

commit810f6f520c8616ff04e1914127a34f4c41c17966
parent40e2b3ac21
authorLucas Galante <lsgalante12@gmail.com>
date2026-10-07 22:08
refactor: hold widgets in Owned boxes (cce-ui Owned<W>)

The UiContext registry keeps raw pointers to registered widgets, and a
widget that moved while registered (its Vec reallocating, its struct
returned by value) left one pointing at the old address. Each widget
field is now an Owned<Adapted<..>> — a heap box whose allocation, not the
widget, carries the liveness token the registry watches — so the
registered address never moves and is dropped from the registry when the
box is freed. Field access is unchanged through Deref; construction
sites wrap in Owned::new.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

 src/main.rs | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index ae7e3bf..5b5a4fe 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,3 +1,4 @@
+use cce_ui::widget::Owned;
 use cce_ui::engine::{Application, WindowSettings, LogicalSize, LogicalPosition, EngineState};
 use cce_ui::widget::{
     Adapted, Button, WidgetHost, EventCtx, UiContext, MouseButton, ElementState, KeyEvent,
@@ -405,9 +406,9 @@ enum Message {
 // ── ColorApp State ───────────────────────────────────────────────────
 
 struct ColorApp {
-    apply_btn: cce_ui::widget::Adapted<cce_ui::widget::Button>,
-    cancel_btn: cce_ui::widget::Adapted<cce_ui::widget::Button>,
-    sliders: Vec<Adapted<ColorSlider>>,
+    apply_btn: Owned<cce_ui::widget::Adapted<cce_ui::widget::Button>>,
+    cancel_btn: Owned<cce_ui::widget::Adapted<cce_ui::widget::Button>>,
+    sliders: Vec<Owned<Adapted<ColorSlider>>>,
 
     red: f32,
     green: f32,
@@ -741,9 +742,9 @@ impl Application for ColorApp {
         }
 
         let mut app = Self {
-            apply_btn,
-            cancel_btn,
-            sliders,
+            apply_btn: Owned::new(apply_btn),
+            cancel_btn: Owned::new(cancel_btn),
+            sliders: sliders.into_iter().map(Owned::new).collect(),
             red: r,
             green: g,
             blue: b,