Keep a contract only where it still holds for this widget
`redraw` keeps the narrower of an old and a fresh contract so that widening and narrowing back do not churn the parent that reads it. The drawing's half asked whether the old range still covers this window and box before keeping it; the answer's half did not, so a widget whose answer contract widened in a frame that also resized the window kept a range the new window is outside. The parent's next ask then refuses that answer and draws the whole subtree again -- throwing away the drawing the widget had just made. Cost, not geometry: the size kept is the size just reported. `a_contract_this_window_is_outside_is_not_kept` draws the leaf twice before the change and once after.
This commit is contained in:
1 parent
781199a7c9
commit
d8d51221ee
2 files changed
+54
-11
No files matched your search
+13
-10
@@ -1108,20 +1108,23 @@ impl UiRenderState {
|
||||
let old = self.remove(id, false, rsc);
|
||||
let drawn = self.draw_inner(id, info, old, rsc);
|
||||
let active = self.active.get_mut(&id).unwrap();
|
||||
// A wider contract does not invalidate the guarantee the parent kept.
|
||||
// Retain that guarantee so widening and narrowing back do not churn it.
|
||||
if let Some(was) = was_answer
|
||||
&& drawn.answer.size == was.size
|
||||
&& drawn.answer.holds.covers(was.holds)
|
||||
{
|
||||
active.answer = was_answer;
|
||||
}
|
||||
// Against the box it was asked in, which is what both contracts are
|
||||
// about. Where the answer put the drawing is shorter than that
|
||||
// wherever the widget reported less than it was offered.
|
||||
if active.holds.covers(was_holds)
|
||||
&& was_holds.contains(self.output_size, active.rel_base, active.region)
|
||||
let (window, rel_base, region) = (self.output_size, active.rel_base, active.region);
|
||||
// A wider contract does not invalidate the guarantee the parent kept.
|
||||
// Retain that guarantee so widening and narrowing back do not churn
|
||||
// it -- but only where the narrower range still holds here: one this
|
||||
// window is outside is refused by the parent's next ask, and refusing
|
||||
// it throws away the drawing this one just made.
|
||||
if let Some(was) = was_answer
|
||||
&& drawn.answer.size == was.size
|
||||
&& drawn.answer.holds.covers(was.holds)
|
||||
&& was.holds.contains(window, rel_base, region)
|
||||
{
|
||||
active.answer = was_answer;
|
||||
}
|
||||
if active.holds.covers(was_holds) && was_holds.contains(window, rel_base, region) {
|
||||
active.holds = was_holds;
|
||||
}
|
||||
if active.answer != was_answer || active.holds != was_holds {
|
||||
|
||||
Reference in new issue
Block a user