Carry a span's rest weight up instead of collapsing it to one share
A span reporting `Len::default()` whenever a child had a share threw away how many shares it was holding, so each level of nesting re-divided a share rather than dividing the same space. One span of a rect beside a span of three gave 1/2 and 1/6 each, where the same four rects directly in one span get a quarter. A span that sizes from its children does not resolve `rest`, it passes the weight up; resolution belongs at the nearest ancestor with a length, and since the output became a box there is always one. The placement loop already divides by `len.rest / total.rest`, so it consumes carried weights unchanged -- only what the span reported was wrong. The uneven nesting is the case that fails without this; the even one passes either way and is here as the statement of intent. Decided by the owner, 2026-09-14. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ef815dadfd
commit
b165164e59
2 files changed
+51
-4
No files matched your search
@@ -60,10 +60,14 @@ impl Widget for Span {
|
||||
start.px += self.gap;
|
||||
}
|
||||
|
||||
let along = match total.rest == 0.0 && total.rel == 0.0 {
|
||||
true => total,
|
||||
false => Len::default(),
|
||||
};
|
||||
// Carried whole rather than collapsed to one share: a span that sizes
|
||||
// from its children does not resolve `rest`, it passes the weight up,
|
||||
// so nesting spans divides the same space rather than re-dividing a
|
||||
// share of it. Four `rest(1)` children under two spans under one span
|
||||
// get a quarter each, which collapsing to `rest(1)` per level does
|
||||
// not give. Resolution happens at the nearest ancestor with a length,
|
||||
// and the root always has one.
|
||||
let along = total;
|
||||
Size::from_axis(axis, along, ortho)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user