From d63f1abcdd6112c8a0cdfb917bfb4bba2bdd6a3e Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 3 Jul 2025 16:11:37 +0200 Subject: [PATCH] workspace: Correctly handle unmapping maximized elements --- src/shell/mod.rs | 8 ++++++-- src/shell/workspace.rs | 35 ++++++++++++++++++----------------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 5795e926..989bb811 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -3489,7 +3489,9 @@ impl Shell { let mut new_size = if mapped.maximized_state.lock().unwrap().is_some() { // If surface is maximized then unmaximize it - workspace.unmaximize_request(&mapped) + workspace + .unmaximize_request(&mapped) + .map(|geo| geo.size.as_logical()) } else { None }; @@ -4139,7 +4141,9 @@ impl Shell { None } } else if let Some(workspace) = self.space_for_mut(mapped) { - workspace.unmaximize_request(mapped) + workspace + .unmaximize_request(mapped) + .map(|geo| geo.size.as_logical()) } else { None } diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index d2bf7c8b..8b7cdbcd 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -574,10 +574,9 @@ impl Workspace { pub fn unmap_element(&mut self, mapped: &CosmicMapped) -> Option { let was_maximized = if mapped.maximized_state.lock().unwrap().is_some() { // If surface is maximized then unmaximize it, so it is assigned to only one layer - let _ = self.unmaximize_request(&mapped); - true + self.unmaximize_request(&mapped) } else { - false + None }; self.focus_stack @@ -598,20 +597,24 @@ impl Workspace { }); } - if let Some(floating_geometry) = self.floating_layer.unmap(&mapped, None) { - return Some(WorkspaceRestoreData::Floating(Some(FloatingRestoreData { - geometry: floating_geometry, - output_size: self.output.geometry().size.as_logical(), - was_maximized, - }))); - }; if let Ok(state) = self.tiling_layer.unmap(&mapped, None) { return Some(WorkspaceRestoreData::Tiling(Some(TilingRestoreData { state, - was_maximized, + was_maximized: was_maximized.is_some(), }))); } + // unmaximize_request might have triggered a `floating_layer.refresh()`, + // which may have already removed a non-alive surface. + if let Some(floating_geometry) = self.floating_layer.unmap(&mapped, None).or(was_maximized) + { + return Some(WorkspaceRestoreData::Floating(Some(FloatingRestoreData { + geometry: floating_geometry, + output_size: self.output.geometry().size.as_logical(), + was_maximized: was_maximized.is_some(), + }))); + }; + None } @@ -935,12 +938,12 @@ impl Workspace { self.floating_layer.recalculate(); } - pub fn unmaximize_request(&mut self, elem: &CosmicMapped) -> Option> { + pub fn unmaximize_request(&mut self, elem: &CosmicMapped) -> Option> { let mut state = elem.maximized_state.lock().unwrap(); if let Some(state) = state.take() { if let Some(minimized) = self.minimized_windows.iter_mut().find(|m| *m == elem) { minimized.unmaximize(state.original_geometry); - Some(state.original_geometry.size.as_logical()) + Some(state.original_geometry) } else { match state.original_layer { ManagedLayer::Tiling if self.tiling_enabled => { @@ -951,9 +954,7 @@ impl Workspace { elem.set_geometry(state.original_geometry.to_global(&self.output)); elem.configure(); self.tiling_layer.recalculate(); - self.tiling_layer - .element_geometry(&elem) - .map(|geo| geo.size.as_logical()) + self.tiling_layer.element_geometry(&elem) } ManagedLayer::Sticky => unreachable!(), _ => { @@ -964,7 +965,7 @@ impl Workspace { Some(state.original_geometry.size.as_logical()), None, ); - Some(state.original_geometry.size.as_logical()) + Some(state.original_geometry) } } }