Skip to content

Allow child UIs to opt out of inherited sizing mode - #8762

Open
yay wants to merge 3 commits into
emilk:mainfrom
yay:codex/no-sizing-pass
Open

yay wants to merge 3 commits into
emilk:mainfrom
yay:codex/no-sizing-pass

Conversation

@yay

@yay yay commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

Add UiBuilder::no_sizing_pass() so a child can use normal layout inside a sizing parent while retaining its actual ancestry and inherited UI properties. This is useful for clipped contents whose size does not determine their container’s allocation.

Default inheritance remains unchanged. The override does not cancel pass discarding or change visibility, enabled state, or input handling.

Compatibility: the public UiBuilder::sizing_pass field changes from bool to Option<bool> (None inherits). Existing callers that assign the field directly need to use Some(...) or the builder methods.

Example: simplifying a fixed-viewport content UI

The override replaces a separate root and reconstructed ancestor chain with a normal child:

-let mut builder = UiBuilder::new()
+let builder = UiBuilder::new()
     .scope_id(id)
     .max_rect(viewport)
     .layer_id(layer)
     .layout(layout)
-    .style(parent.style().clone())
-    .accessibility_parent(parent.unique_id());
-
-if !parent.is_enabled() {
-    builder = builder.disabled();
-}
-
-let mut content = if parent.is_sizing_pass() {
-    let ancestors: Vec<_> = parent.stack().iter().collect();
-    let mut proxy: Option<Ui> = None;
-    for (index, ancestor) in ancestors.into_iter().rev().enumerate() {
-        let mut ancestor_builder = UiBuilder::new()
-            .ui_stack_info(ancestor.info.clone())
-            .max_rect(ancestor.max_rect)
-            .layer_id(layer);
-        ancestor_builder.classes = ancestor.classes.clone();
-        let ancestor_id = id.with(("sizing-ancestor", index));
-        proxy = Some(if let Some(parent) = &mut proxy {
-            parent.new_child(ancestor_builder.scope_id(ancestor_id))
-        } else {
-            Ui::new(parent.ctx().clone(), ancestor_id, ancestor_builder)
-        });
-    }
-    proxy.unwrap().new_child(builder)
-} else {
-    parent.new_child(builder)
-};
+    .no_sizing_pass();
+
+let mut content = parent.new_child(builder);

The actual parent chain also keeps ui.close() and ui.close_kind() working without copying container metadata.

Tests cover inheritance and override precedence, widget layout, live ancestry and closing, inherited properties, and unchanged discard/input behavior.

Closes #8760.

  • I have followed the instructions in the PR template

@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Preview available at https://egui-pr-preview.github.io/pr/8762-codexno-sizing-pass
Note that it might take a couple seconds for the update to show up after the preview_build workflow has completed.

View snapshot changes at kitdiff

@yay
yay force-pushed the codex/no-sizing-pass branch from 1778e84 to 81b9edc Compare October 22, 2026 13:36
@yay
yay force-pushed the codex/no-sizing-pass branch from 81b9edc to c433904 Compare October 22, 2026 14:03
@yay
yay marked this pull request as ready for review October 22, 2026 14:10
@yay
yay requested a review from lucasmerlin as a code owner October 22, 2026 14:10

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow child UIs to opt out of inherited sizing mode

1 participant