diff --git a/src/shell/grabs/moving.rs b/src/shell/grabs/moving.rs index f59f93d6..8b01d086 100644 --- a/src/shell/grabs/moving.rs +++ b/src/shell/grabs/moving.rs @@ -906,20 +906,22 @@ impl Drop for MoveGrab { } } } else { - let mut shell = state.common.shell.write(); - shell - .workspaces - .active_mut(&cursor_output) - .unwrap() - .tiling_layer - .cleanup_drag(); - shell.set_overview_mode(None, state.common.event_loop_handle.clone()); None } } else { None }; + let mut shell = state.common.shell.write(); + shell + .workspaces + .active_mut(&cursor_output) + .unwrap() + .tiling_layer + .cleanup_drag(); + shell.set_overview_mode(None, state.common.event_loop_handle.clone()); + drop(shell); + { let cursor_state = seat.user_data().get::().unwrap(); cursor_state.lock().unwrap().unset_shape(); 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); + } } }