Pin a frame by the fraction the child declared
`size_hint` resolves a child's hint against the asking widget's frame and pins that frame, so a later draw cannot reuse a resolution made against a different one. It asked the *resolved* hint whether it still had a fraction, which is false whenever the frame is itself pixels -- a slot of a row, or the box a stack's sizing child decided -- and the pin was dropped there. Ask the declared hint, which is what made this draw depend on the frame, and what `ruled` in `render_state` already asks for a rule. No generated tree distinguishes the two: the fuzzer grows no `rel` rules, and a frame that changes almost always changes a box the other pins catch. Kept for the reason the `frame_len` pin beside it is kept -- "these two invalidations always coincide" is an assumption nothing states.
This commit is contained in:
1 parent
f6242aa33c
commit
38b3a81053
1 file changed
+23
-27
+23
-27
@@ -267,36 +267,32 @@ impl<'a> Painter<'a> {
|
|||||||
let widgets = self.rsc.widgets();
|
let widgets = self.rsc.widgets();
|
||||||
// A rule is the answer where there is one: it wins over whatever the
|
// A rule is the answer where there is one: it wins over whatever the
|
||||||
// widget would draw, so it has to win over what the widget says too.
|
// widget would draw, so it has to win over what the widget says too.
|
||||||
let hint = widgets
|
let hint = widgets.size_rules(id.id()).axis(axis).exact().or_else(|| {
|
||||||
.size_rules(id.id())
|
widgets
|
||||||
.axis(axis)
|
.get_dyn(id.id())
|
||||||
.exact()
|
.and_then(|widget| widget.size_hint(axis))
|
||||||
.or_else(|| {
|
});
|
||||||
widgets
|
let frame = self.frame.axis(axis);
|
||||||
.get_dyn(id.id())
|
let resolved = hint.map(|hint| hint.within_len(frame));
|
||||||
.and_then(|widget| widget.size_hint(axis))
|
|
||||||
})
|
|
||||||
.map(|hint| hint.within_len(self.frame.axis(axis)));
|
|
||||||
#[cfg(feature = "layout-diagnostics")]
|
#[cfg(feature = "layout-diagnostics")]
|
||||||
diag::hint_read(id.id(), self.id, axis, hint);
|
{
|
||||||
match hint {
|
diag::hint_read(id.id(), self.id, axis, resolved);
|
||||||
Some(hint) => {
|
diag::bump(match resolved {
|
||||||
#[cfg(feature = "layout-diagnostics")]
|
Some(_) => Counter::HintHits,
|
||||||
diag::bump(Counter::HintHits);
|
None => Counter::HintMisses,
|
||||||
self.depend_on(id);
|
});
|
||||||
// A fraction was just resolved against this frame, so what
|
}
|
||||||
// this draw does with it is a function of the frame's length.
|
if let Some(hint) = hint {
|
||||||
if hint.rel != Rel::ZERO {
|
self.depend_on(id);
|
||||||
self.frame_own_len[axis as usize] = Some(self.frame.axis(axis));
|
// Resolving a fraction against this frame makes this draw a
|
||||||
}
|
// function of the frame's length. The fraction to ask about is
|
||||||
Some(hint)
|
// the child's own: resolved against a frame of pixels, none is
|
||||||
}
|
// left to see it by.
|
||||||
None => {
|
if hint.rel != Rel::ZERO {
|
||||||
#[cfg(feature = "layout-diagnostics")]
|
self.frame_own_len[axis as usize] = Some(frame);
|
||||||
diag::bump(Counter::HintMisses);
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
resolved
|
||||||
}
|
}
|
||||||
|
|
||||||
fn depend_on<W: ?Sized>(&mut self, child: &StrongWidget<W>) {
|
fn depend_on<W: ?Sized>(&mut self, child: &StrongWidget<W>) {
|
||||||
|
|||||||
Reference in new issue
Block a user