Skip to content

Commit

Permalink
Propagate the stashed state correctly (#613)
Browse files Browse the repository at this point in the history
When the scrollbars are not being set, the calculations get NaNs. This
breaks rendering, causing extreme slowdowns and artifacts.

This is discussed in [#masonry>`to_do_list`: Horrendous
performance](https://xi.zulipchat.com/#narrow/stream/317477-masonry/topic/to_do_list.3A.20Horrendous.20performance)

I've made this work now using `is_explicitly_stashed` in layout. It does
not currently cause issues there.

The underlying issue of `NaN`s being created (and not detected) have not
been resolved.
  • Loading branch information
DJMcNab authored Sep 27, 2024
1 parent 997da03 commit 7fb9456
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 3 deletions.
10 changes: 8 additions & 2 deletions masonry/src/contexts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -618,8 +618,14 @@ impl_context_method!(
///
/// **Note:** Stashed widgets are a WIP feature.
pub fn set_stashed(&mut self, child: &mut WidgetPod<impl Widget>, stashed: bool) {
self.get_child_state_mut(child).needs_update_stashed = true;
self.get_child_state_mut(child).is_explicitly_stashed = stashed;
let child_state = self.get_child_state_mut(child);
// Stashing is generally a property derived from the parent widget's state
// (rather than set imperatively), so it is likely to be set as part of passes.
// Therefore, we avoid re-running the update_stashed_pass in most cases.
if child_state.is_explicitly_stashed != stashed {
child_state.needs_update_stashed = true;
child_state.is_explicitly_stashed = stashed;
}
}
}
);
Expand Down
6 changes: 5 additions & 1 deletion masonry/src/passes/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,11 @@ pub(crate) fn run_layout_inner<W: Widget>(
let widget = widget_mut.item;
let state = state_mut.item;

if state.is_stashed {
// The parent (and only the parent) controls the stashed state, and it is valid to set `stashed` in layout.
// Because of that, we use the local value rather than the global value.
// Note that if we are stashed by a grandparent, this check would trigger for that grandparent, so we should
// never be called.
if state.is_explicitly_stashed {
debug_panic!(
"Error in '{}' #{}: trying to compute layout of stashed widget.",
widget.short_type_name(),
Expand Down
1 change: 1 addition & 0 deletions masonry/src/widget/widget_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ impl WidgetState {
self.has_focus |= child_state.has_focus;
self.children_changed |= child_state.children_changed;
self.update_focus_chain |= child_state.update_focus_chain;
self.needs_update_stashed |= child_state.needs_update_stashed;
}

#[inline]
Expand Down

0 comments on commit 7fb9456

Please sign in to comment.