diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index ffeeb52a..85efb2ce 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -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::>() - .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); + } } }