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

commit05dc785942cdac99f9ac0c075d6592498844e1e5
parentc481489fe0
authorLucas Galante <[email protected]>
date2026-07-12 16:50
refactor(widget): delete dead container child-ptr storage (Phase 6bc slice 3)

Census of stored *mut dyn Element struct fields found the container
child vecs slated for the id retype are almost all ballast:
ParametersBg.children was never populated anywhere in the workspace
(the only add_child path is link_parent_child, used solely by
display-manager on its card), so its field, its parent-tracking twin
(parent + parent_changed/tracked_parent — Adapted::parent falls back
to the tree, identical result), the container hooks, eleven dead
iteration blocks, the collect_child_quads helper, and window_runner's
quad-attribution loop are deleted. ScrollBox.children was write-only
(one push in cce-test-interface's ControlPanel copy) and is deleted.

What remains stored after this slice: the WidgetTree registry (by
design) and TI's ControlPanel.children — live, pointing into boxed
slots, consumed in ctx-less paint/arrange paths; it retypes when
those paths gain ctx (the Element/Adapted endgame). Paginator's
container_children is a transient field ref, not storage.

Verified: 168 tests (one pre-existing flake re-passed); workspace
builds; designer smoke — params panel renders, HTTP add_node works.

 src/backend/window_runner.rs          |   7 --
 src/widget/container/parameters_bg.rs | 143 +---------------------------------
 src/widget/container/scroll_box.rs    |   2 -
 3 files changed, 1 insertion(+), 151 deletions(-)

diff --git a/src/backend/window_runner.rs b/src/backend/window_runner.rs
index 536801d..4dbd156 100644
--- a/src/backend/window_runner.rs
+++ b/src/backend/window_runner.rs
@@ -1186,13 +1186,6 @@ fn get_child_widget_for_quad<'a>(
                 }
             }
         }
-        for &child_ptr in &pbg.children {
-            let child = unsafe { &*child_ptr };
-            let (cx, cy, cww, chh) = child.rect();
-            if qx >= cx - 0.1 && qx + qw <= cx + cww + 0.1 && qy >= cy - 0.1 && qy + qh <= cy + chh + 0.1 {
-                return child;
-            }
-        }
     }
     w
 }
diff --git a/src/widget/container/parameters_bg.rs b/src/widget/container/parameters_bg.rs
index 1433fdf..9e44da9 100644
--- a/src/widget/container/parameters_bg.rs
+++ b/src/widget/container/parameters_bg.rs
@@ -47,8 +47,6 @@ pub struct ParametersBg {
     pub checkboxes: Vec<Option<Adapted<Checkbox>>>,
     pub colors: Vec<Option<crate::widget::Adapted<ColorSelector>>>,
     visible: bool,
-    pub children: Vec<*mut (dyn Element + 'static)>,
-    pub parent: Option<*mut (dyn Element + 'static)>,
     pub scroll_y: f32,
     pub content_h: f32,
     scrollbar_dragging: bool,
@@ -73,8 +71,6 @@ impl ParametersBg {
             checkboxes: Vec::new(),
             colors: Vec::new(),
             visible: true,
-            children: Vec::new(),
-            parent: None,
             scroll_y: 0.0,
             content_h: 0.0,
             scrollbar_dragging: false,
@@ -330,12 +326,6 @@ impl ParametersBg {
         if let Some(r) = self.choices_popover_rect() {
             return Some(r);
         }
-        for &widget_ptr in self.children.iter().rev() {
-            let widget = unsafe { &*widget_ptr };
-            if let Some(r) = widget.popover_rect() {
-                return Some(r);
-            }
-        }
         None
     }
 
@@ -394,11 +384,6 @@ impl ParametersBg {
             }
         }
         self.focused_param = None;
-
-        for &child_ptr in &self.children {
-            let child = unsafe { &mut *child_ptr };
-            child.unfocus();
-        }
     }
 
     /// The legacy `extra_quads` body: section border boxes, every row's chrome (slider/spinbox
@@ -540,13 +525,6 @@ impl ParametersBg {
             }
         }
 
-        for &child_ptr in &self.children {
-            let child = unsafe { &*child_ptr };
-            if child.visible() {
-                param_quads.extend(collect_child_quads(child));
-            }
-        }
-
         // Clip all parameter quads vertically
         for q in param_quads {
             if let Some(clipped) = clip_quad(q) {
@@ -582,30 +560,6 @@ impl ParametersBg {
 }
 
 impl Layout for ParametersBg {
-    fn has_container_children(&self) -> bool {
-        true
-    }
-
-    fn container_children(&self) -> Vec<*mut (dyn Element + 'static)> {
-        self.children.clone()
-    }
-
-    fn child_added(&mut self, child: *mut (dyn Element + 'static)) {
-        self.children.push(child);
-    }
-
-    fn children_cleared(&mut self) {
-        self.children.clear();
-    }
-
-    fn parent_changed(&mut self, parent: Option<*mut (dyn Element + 'static)>) {
-        self.parent = parent;
-    }
-
-    fn tracked_parent(&self) -> Option<Option<*mut (dyn Element + 'static)>> {
-        Some(self.parent)
-    }
-
     /// Ungated rect landing (the legacy `set_rect` head, before its visibility gate): cache the
     /// rect all row geometry derives from, then re-derive content height/scroll/row rects.
     fn rect_assigned(&mut self, rect: Rect) {
@@ -613,24 +567,6 @@ impl Layout for ParametersBg {
         self.refresh_scroll_metrics();
     }
 
-    /// The legacy `set_rect` tail (visible-gated there and by the adapter here): stack the raw
-    /// container children vertically.
-    fn arrange_children(&mut self, rect: Rect, _host: *mut (dyn Element + 'static)) {
-        let padding_x = 8.0;
-        let padding_y = 10.0;
-        let left_x = rect.x + padding_x;
-        let available_w = (rect.width - 2.0 * padding_x).max(1.0);
-        let mut current_y = rect.y + padding_y;
-        let spacing = 8.0;
-
-        for &child_ptr in &self.children {
-            let child = unsafe { &mut *child_ptr };
-            let (_, _, _, ch) = child.rect();
-            let use_h = if ch > 0.0 { ch } else { 42.0 };
-            child.set_rect(left_x, current_y, available_w, use_h);
-            current_y += use_h + spacing;
-        }
-    }
 }
 
 impl Paint for ParametersBg {
@@ -684,7 +620,7 @@ impl Paint for ParametersBg {
     /// The legacy `text_labels_with_font_and_bounds` body: every label clipped to the panel
     /// viewport in the control-label font, except labels inside a code row — those clip to the
     /// code box (or hide when it's scrolled out) and render monospace.
-    fn legacy_labels_with_font_and_bounds(&self, _rect: Rect, ctx: &UiContext) -> Vec<(TextLabel, Option<String>, Option<[f32; 4]>)> {
+    fn legacy_labels_with_font_and_bounds(&self, _rect: Rect, _ctx: &UiContext) -> Vec<(TextLabel, Option<String>, Option<[f32; 4]>)> {
         let view_min = self.rect.y + 4.0;
         let view_max = self.rect.y + self.rect.height - 4.0;
         let mut result = Vec::new();
@@ -714,17 +650,6 @@ impl Paint for ParametersBg {
             }
             result.push((l, label_font, bounds));
         }
-        for &child_ptr in &self.children {
-            // The trait text getters are gone: the raw children's labels come off the
-            // paint walk (fonts + clip bounds composed into the prims).
-            let mut scratch = crate::scene::paint::PaintCtx::new();
-            crate::scene::painter::append_widget_text(ctx, unsafe { &*child_ptr }, &mut scratch);
-            for item in scratch.finish().items {
-                if let crate::scene::paint::Prim::Text { text, x, y, font_size, color, font, bounds, .. } = item.prim {
-                    result.push((TextLabel { text, x, y, font_size, color }, font, bounds));
-                }
-            }
-        }
         result
     }
 
@@ -1003,16 +928,6 @@ impl Input for ParametersBg {
                     }
                 }
 
-                for &widget_ptr in &self.children {
-                    let widget = unsafe { &mut *widget_ptr };
-                    if widget.is_dragging() {
-                        if widget.drag_update(px, py) {
-                            changed = true;
-                        }
-                    } else if widget.cursor_moved(px, py, ui) {
-                        changed = true;
-                    }
-                }
                 changed
             }
             Event::MouseButton { button, state, x: px, y: py, .. } => {
@@ -1084,15 +999,6 @@ impl Input for ParametersBg {
                     }
                 }
 
-                for &widget_ptr in self.children.iter().rev() {
-                    let widget = unsafe { &mut *widget_ptr };
-                    if widget.popover_rect().is_some() {
-                        if widget.mouse_input(button, state, px, py, ui) {
-                            return true;
-                        }
-                    }
-                }
-
                 // 2. Propagate to our widgets
                 for (i, p) in self.display_params.iter_mut().enumerate() {
                     if p.2.starts_with("choice") {
@@ -1177,16 +1083,6 @@ impl Input for ParametersBg {
                     }
                 }
 
-                for &widget_ptr in self.children.iter().rev() {
-                    let widget = unsafe { &mut *widget_ptr };
-                    if widget.mouse_input(button, state, px, py, ui) {
-                        return true;
-                    }
-                    if state == ElementState::Pressed && !widget.hit_test(px, py, ui) {
-                        widget.unfocus();
-                    }
-                }
-
                 if button == MouseButton::Left && state == ElementState::Pressed {
                     let rects = self.get_param_rects();
                     let mut clicked_any_focusable = false;
@@ -1247,13 +1143,6 @@ impl Input for ParametersBg {
                 let Some(ui) = ectx.ui.as_deref_mut() else {
                     return false;
                 };
-                for &widget_ptr in &self.children {
-                    let widget = unsafe { &mut *widget_ptr };
-                    if widget.keyboard_input(event, ui) {
-                        return true;
-                    }
-                }
-
                 if let Some(idx) = self.focused_param {
                     if event.state == ElementState::Pressed {
                         let p = &mut self.display_params[idx];
@@ -1472,13 +1361,6 @@ impl Input for ParametersBg {
                 let Some(ui) = ectx.ui.as_deref_mut() else {
                     return false;
                 };
-                for &widget_ptr in self.children.iter().rev() {
-                    let widget = unsafe { &mut *widget_ptr };
-                    if widget.mouse_wheel(delta, px, py, ui) {
-                        return true;
-                    }
-                }
-
                 let mut changed = false;
                 let rects = self.get_param_rects();
                 for (i, p) in self.display_params.iter_mut().enumerate() {
@@ -1646,29 +1528,6 @@ fn parse_float3_value(val_str: &str, min: f32, max: f32) -> [f32; 3] {
     out
 }
 
-fn collect_child_quads(widget: &dyn Element) -> Vec<(f32, f32, f32, f32, [f32; 4])> {
-    let mut quads = Vec::new();
-    let c = widget.color();
-    let (wx, wy, ww, wh) = widget.rect();
-    let has_bg = c[3].abs() > 0.001;
-    let extra = widget.extra_quads();
-    let already_has_bg = extra.iter().any(|q| {
-        (q.0 - wx).abs() < 0.1 && (q.1 - wy).abs() < 0.1 && (q.2 - ww).abs() < 0.1 && (q.3 - wh).abs() < 0.1
-    });
-    if has_bg && !already_has_bg {
-        quads.push((wx, wy, ww, wh, c));
-    }
-    quads.extend(extra);
-    let dummy_ctx = UiContext::new();
-    for &child_ptr in &widget.children(&dummy_ctx) {
-        let child = unsafe { &*child_ptr };
-        if child.visible() {
-            quads.extend(collect_child_quads(child));
-        }
-    }
-    quads
-}
-
 impl ParamController for ParametersBg {
     fn node_params(&self) -> Vec<(String, String, String)> {
         self.display_params.clone()
diff --git a/src/widget/container/scroll_box.rs b/src/widget/container/scroll_box.rs
index 25dfd77..f509ddc 100644
--- a/src/widget/container/scroll_box.rs
+++ b/src/widget/container/scroll_box.rs
@@ -18,7 +18,6 @@ pub struct ScrollBox {
     viewport_offset_h: f32,
     pub show_border: bool,
     pub show_background: bool,
-    pub children: Vec<*mut (dyn Element + 'static)>,
     pub scrollbar_dragging: bool,
     pub drag_offset_y: f32,
 }
@@ -35,7 +34,6 @@ impl ScrollBox {
             viewport_offset_h: 0.0,
             show_border: true,
             show_background: true,
-            children: Vec::new(),
             scrollbar_dragging: false,
             drag_offset_y: 0.0,
         }