Retain request dependencies only when discovery supplies the answer

This commit is contained in:
iris-ai committed 2026-09-20 17:31:53 -04:00
1 parent 8780b40bb7
commit 0e838e9dd1
7 files changed
+183 -50

No files matched your search

+38 -18
View File
@@ -87,29 +87,37 @@ impl<'a> Painter<'a> {
child: &StrongWidget<W>,
axis: Axis,
) -> Option<RequestedLen> {
self.request_deps.push(child.id());
if self.rsc.widgets().size_rules(child.id())[axis].bound() == crate::Bound::ANY
&& let Some(len) = self.size_hint(child, axis)
{
self.request_deps.push(child.id());
return Some(len.into());
}
let rel_base = self.rel_base(axis);
let start = self.request_deps.len();
let mut requests = SizeRequests {
arena: &mut self.state.requests,
measured: None,
widgets: self.rsc.widgets(),
dependencies: &mut self.request_deps,
rel_base,
rel_base: self.rel_base[axis],
};
let request = requests.widget(child, axis)?;
// An intrinsic fixed answer still draws in the offered room and is
// moved afterwards. Only a declaration or a share chooses its ask box.
(request.has_leftover()
|| matches!(
self.rsc.widgets().size_rules(child.id())[axis],
crate::SizeRule::Request(_)
))
.then_some(request)
// Intrinsic fixed content must keep its offered box for wrapping;
// only a declaration or a share chooses the box it is drawn in.
let request = requests.widget(child, axis).filter(|request| {
request.has_leftover()
|| matches!(
self.rsc.widgets().size_rules(child.id())[axis],
crate::SizeRule::Request(_)
)
});
if request.is_some() {
self.rel_base(axis);
} else {
// A discarded request contributes no dependency: the measured
// draw below records the size and box it actually used instead.
self.request_deps.truncate(start);
}
request
}
/// Completes discovery after a child was measured. Only this call may use
@@ -120,20 +128,32 @@ impl<'a> Painter<'a> {
axis: Axis,
len: LayoutLen,
) -> RequestedLen {
let rel_base = self.rel_base(axis);
let start = self.request_deps.len();
let bound = self.rsc.widgets().size_rules(child.id())[axis].bound();
let mut requests = SizeRequests {
arena: &mut self.state.requests,
measured: Some(&self.state.active),
widgets: self.rsc.widgets(),
dependencies: &mut self.request_deps,
rel_base,
rel_base: self.rel_base[axis],
};
match requests.widget(child, axis) {
Some(request) if request.linear().is_none() && request.has_leftover() => request,
_ if len.leftover > Weight::ZERO => requests.bounded(len.into(), bound),
_ => len.into(),
if let Some(request) = requests.widget(child, axis)
&& request.linear().is_none()
&& request.has_leftover()
{
self.rel_base(axis);
return request;
}
let request = if len.leftover > Weight::ZERO {
requests.bounded(len.into(), bound)
} else {
len.into()
};
self.request_deps.truncate(start);
if len.leftover > Weight::ZERO && bound != crate::Bound::ANY {
self.rel_base(axis);
}
request
}
/// A deferred comparison reads this window when the allocation is solved.