Merge pull request #2077 from pop-os/cleanup-drag_noble

layout/tiling: Fix panic from tiling placeholders not being cleaned up
This commit is contained in:
Levi Portenier 2026-02-12 12:57:27 -07:00 committed by GitHub
commit 67c08ef692
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 33 additions and 23 deletions

View file

@ -906,20 +906,22 @@ impl Drop for MoveGrab {
} }
} }
} else { } 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 None
} }
} else { } else {
None 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::<CursorState>().unwrap(); let cursor_state = seat.user_data().get::<CursorState>().unwrap();
cursor_state.lock().unwrap().unset_shape(); cursor_state.lock().unwrap().unset_shape();

View file

@ -2637,28 +2637,36 @@ impl TilingLayout {
} }
pub fn cleanup_drag(&mut self) { 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) = old_tree.root_node_id() {
for id in old_tree.traverse_pre_order_ids(root).unwrap() {
if let Some(root) = tree.root_node_id() { match old_tree.get(&id).map(|node| node.data()) {
for id in tree Ok(Data::Placeholder { .. }) => {
.traverse_pre_order_ids(root) // Copy a tree on write
.unwrap() let new_tree = new_tree.get_or_insert_with(|| old_tree.copy_clone());
.collect::<Vec<_>>() TilingLayout::unmap_internal(new_tree, &id)
.into_iter() }
{
match tree.get_mut(&id).map(|node| node.data_mut()) {
Ok(Data::Placeholder { .. }) => TilingLayout::unmap_internal(&mut tree, &id),
Ok(Data::Group { pill_indicator, .. }) if pill_indicator.is_some() => { 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); // If anything was changed, push updated tree
self.queue.push_tree(tree, ANIMATION_DURATION, blocker); 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);
}
} }
} }