layout/tiling: Make cleanup_drag push tree only if something changes
Since `copy_clone()` preserved IDs, `traverse_pre_order_ids()` can be called on the old tree, without collecting into a `Vec`. Then we can also `copy_clone()` only if there's actually a change, and also only call `push_tree()` in that case. (Once the `LazyCell::get()` stabilization is released, we could use that here, but `Option::get_or_insert_with()` may be more readable anyway.) With this, `cleanup_drag()` should be pretty low-cost, so we shouldn't have to worry about whether or not it's redundant.
This commit is contained in:
parent
2ea1186723
commit
de7c78accd
1 changed files with 23 additions and 15 deletions
|
|
@ -2637,28 +2637,36 @@ impl TilingLayout {
|
|||
}
|
||||
|
||||
pub fn cleanup_drag(&mut self) {
|
||||
let gaps = self.gaps();
|
||||
let old_tree = &self.queue.trees.back().unwrap().0;
|
||||
let mut new_tree = None;
|
||||
|
||||
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
||||
|
||||
if let Some(root) = tree.root_node_id() {
|
||||
for id in tree
|
||||
.traverse_pre_order_ids(root)
|
||||
.unwrap()
|
||||
.collect::<Vec<_>>()
|
||||
.into_iter()
|
||||
{
|
||||
match tree.get_mut(&id).map(|node| node.data_mut()) {
|
||||
Ok(Data::Placeholder { .. }) => TilingLayout::unmap_internal(&mut tree, &id),
|
||||
if let Some(root) = old_tree.root_node_id() {
|
||||
for id in old_tree.traverse_pre_order_ids(root).unwrap() {
|
||||
match old_tree.get(&id).map(|node| node.data()) {
|
||||
Ok(Data::Placeholder { .. }) => {
|
||||
// Copy a tree on write
|
||||
let new_tree = new_tree.get_or_insert_with(|| old_tree.copy_clone());
|
||||
TilingLayout::unmap_internal(new_tree, &id)
|
||||
}
|
||||
Ok(Data::Group { pill_indicator, .. }) if pill_indicator.is_some() => {
|
||||
pill_indicator.take();
|
||||
let new_tree = new_tree.get_or_insert_with(|| old_tree.copy_clone());
|
||||
match new_tree.get_mut(&id).unwrap().data_mut() {
|
||||
Data::Group { pill_indicator, .. } => {
|
||||
*pill_indicator = None;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let blocker = TilingLayout::update_positions(&self.output, &mut tree, gaps);
|
||||
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
||||
// If anything was changed, push updated tree
|
||||
if let Some(mut new_tree) = new_tree {
|
||||
let blocker =
|
||||
TilingLayout::update_positions(&self.output, &mut new_tree, self.gaps());
|
||||
self.queue.push_tree(new_tree, ANIMATION_DURATION, blocker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue