GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
refactor(widget): fold zero-override container hooks (6bc census round)
The ParametersBg deletion stranded child_added, children_cleared, and
layout_children_ctx at zero overrides — deleted with their Adapted
call sites (the calls were provable no-ops). RFC records the
remaining deliberate stored-pointer state: the registry, TI's
ControlPanel.children, and the tick-refreshed parent copies in
MenuBar/StatusBar/Dropdown (endgame: snapshot the read data, not the
pointer).
docs/rfc-core-rebuild.md | 15 ++++++++++++++-
src/widget/model.rs | 21 ++-------------------
2 files changed, 16 insertions(+), 20 deletions(-)
diff --git a/docs/rfc-core-rebuild.md b/docs/rfc-core-rebuild.md
index c093e5d..d5ed05b 100644
--- a/docs/rfc-core-rebuild.md
+++ b/docs/rfc-core-rebuild.md
@@ -1808,9 +1808,22 @@ Constraint respected: **each crate still builds standalone** — the new core is
with the `Element` endgame rather than warranting a standalone
signature sweep.
4. **`propagate_event(event, root: WidgetId)`** + the app dispatch
- loops off `as_ptr_mut` (the big app sweep).
+ loops off `as_ptr_mut` (the big app sweep). NOTE from the
+ slice-3 census: propagate roots are live borrows at call time —
+ this slice is API honesty, not a UAF fix; weigh folding it into
+ the endgame instead of touching ~200 app sites twice.
5. window_runner render plumbing + remaining `as_ptr` sites; then
the `Element` + `Adapted` endgame (own design pass).
+ Stored-pointer state remaining after slices 1–3, all deliberate:
+ the `WidgetTree` registry; TI's `ControlPanel.children`; and the
+ tick-refreshed parent copies in MenuBar/StatusBar/Dropdown models
+ (`parent_changed`/`tracked_parent` — written each tick by the
+ re-parenting pattern with the live host pointer, read in ctx-less
+ popover-direction/corner-radius math). Endgame option for the
+ parent copies: snapshot the *data* read through them (parent rect,
+ radius, is-Ramp flag) at re-parent time instead of the pointer —
+ same refresh cadence, no deref of potentially-dead memory; watch
+ the one-frame rect lag on resize if reads move to snapshots.
Order rationale: each phase is independently valuable and reversible, and no phase requires the
next to compile. Phase 0 can land immediately regardless of the rest.
diff --git a/src/widget/model.rs b/src/widget/model.rs
index 751dc41..0b87c04 100644
--- a/src/widget/model.rs
+++ b/src/widget/model.rs
@@ -132,13 +132,6 @@ pub trait Layout {
Vec::new()
}
- /// A child was attached through `Element::add_child` (the adapter has already tree-linked
- /// it and set its parent).
- fn child_added(&mut self, _child: *mut (dyn Element + 'static)) {}
-
- /// All children were detached through `Element::clear_children`.
- fn children_cleared(&mut self) {}
-
/// The parent pointer changed through `Element::set_parent` (containers that clamp their
/// rect to the parent's keep a copy — the tree default needs a ctx that `set_rect` lacks).
fn parent_changed(&mut self, _parent: Option<*mut (dyn Element + 'static)>) {}
@@ -155,10 +148,6 @@ pub trait Layout {
/// ButtonStrip) parent it back to the host so legacy parent-chain styling walks work.
fn arrange_children(&mut self, _rect: Rect, _host: *mut (dyn Element + 'static)) {}
- /// Recursive child layout for the `Element::layout` pass (this one has ctx). Called after
- /// the adapter has measured and placed the container itself, only while visible.
- fn layout_children_ctx(&mut self, _rect: Rect, _ctx: &mut UiContext) {}
-
/// Per-child visibility policy for the adapter's subtree plumbing (Switcher exposes only
/// the active child). Default: every child.
fn child_visible(&self, _child: *mut (dyn Element + 'static)) -> bool {
@@ -922,18 +911,16 @@ impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
ctx.register_widget(c_id, child);
ctx.tree.link(p_id, c_id);
}
- // …plus, for containers, the legacy container extras: parent the child back (Layer,
- // Switcher) and record it in the model's own Vec.
+ // …plus, for containers, the legacy container extra: parent the child back (Layer,
+ // Switcher). (The model-Vec record died with ParametersBg.children — zero overrides.)
if Layout::has_container_children(&self.inner) {
let self_ptr = self.as_ptr_mut();
unsafe { (*child).set_parent(Some(self_ptr), ctx) };
- Layout::child_added(&mut self.inner, child);
}
}
fn clear_children(&mut self, ctx: &mut UiContext) {
ctx.clear_children_ids(self.base.id());
- Layout::children_cleared(&mut self.inner);
}
fn set_parent(&mut self, parent: Option<*mut (dyn Element + 'static)>, ctx: &mut UiContext) {
@@ -995,10 +982,6 @@ impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
self.set_rect(origin.x, origin.y, size.width, size.height);
let host_id = self.base.id();
Layout::register_embedded_children(&mut self.inner, host_id, ctx);
- if Layout::has_container_children(&self.inner) && self.visible {
- let rect = self.content_rect();
- Layout::layout_children_ctx(&mut self.inner, rect, ctx);
- }
}
fn prepare_text(&mut self, fs: &mut glyphon::FontSystem) {