diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 9c2d7ae4..5795e926 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -2443,7 +2443,7 @@ impl Shell { window, original_geometry.map(|rect| rect.loc), original_geometry.map(|rect| rect.size.as_logical()), - None, + Some(set.output.geometry().to_local(&set.output)), ); return; } @@ -2465,6 +2465,7 @@ impl Shell { None => self.workspaces.active_mut(&seat.active_output()).unwrap(), Some(FullscreenRestoreState::Sticky { .. }) => unreachable!(), }; + let fullscreen_geometry = workspace.output.geometry().to_local(&workspace.output); match state { None => { @@ -2472,22 +2473,43 @@ impl Shell { toplevel_enter_workspace(&window.active_window(), &workspace.handle); if workspace.tiling_enabled { - workspace.tiling_layer.map( + workspace.tiling_layer.remap( window, - Some(workspace.focus_stack.get(seat).iter()), + Some(fullscreen_geometry), None, + Some(workspace.focus_stack.get(seat).iter()), ); } else { - workspace.floating_layer.map(window, None); + workspace.floating_layer.map_internal( + window, + None, + None, + Some(fullscreen_geometry), + ); } } - Some(FullscreenRestoreState::Floating { .. }) => { + Some(FullscreenRestoreState::Floating { + state: FloatingRestoreData { was_maximized, .. }, + .. + }) => { workspace.floating_layer.map_internal( - window, + window.clone(), original_geometry.map(|geo| geo.loc), original_geometry.map(|geo| geo.size.as_logical()), - None, + Some(fullscreen_geometry), ); + if was_maximized { + let geometry = workspace.floating_layer.element_geometry(&window).unwrap(); + let mut state = window.maximized_state.lock().unwrap(); + *state = Some(MaximizedState { + original_geometry: geometry, + original_layer: ManagedLayer::Floating, + }); + std::mem::drop(state); + workspace + .floating_layer + .map_maximized(window, fullscreen_geometry, true); + } } Some(FullscreenRestoreState::Tiling { state: @@ -2497,16 +2519,47 @@ impl Shell { }, .. }) => { - let focus_stack = workspace.focus_stack.get(seat); - workspace - .tiling_layer - .remap(window.clone(), None, state, Some(focus_stack.iter())); - if was_maximized { - let previous_geometry = - workspace.tiling_layer.element_geometry(&window).unwrap(); - workspace - .floating_layer - .map_maximized(window, previous_geometry, true); + if workspace.tiling_enabled { + let focus_stack = workspace.focus_stack.get(seat); + workspace.tiling_layer.remap( + window.clone(), + Some(fullscreen_geometry), + state, + Some(focus_stack.iter()), + ); + if was_maximized { + let previous_geometry = + workspace.tiling_layer.element_geometry(&window).unwrap(); + let mut state = window.maximized_state.lock().unwrap(); + *state = Some(MaximizedState { + original_geometry: previous_geometry, + original_layer: ManagedLayer::Tiling, + }); + std::mem::drop(state); + workspace + .floating_layer + .map_maximized(window, fullscreen_geometry, true); + } + } else { + workspace.floating_layer.map_internal( + window.clone(), + None, + None, + Some(fullscreen_geometry), + ); + + if was_maximized { + let geometry = workspace.floating_layer.element_geometry(&window).unwrap(); + let mut state = window.maximized_state.lock().unwrap(); + *state = Some(MaximizedState { + original_geometry: geometry, + original_layer: ManagedLayer::Floating, + }); + std::mem::drop(state); + workspace + .floating_layer + .map_maximized(window, fullscreen_geometry, true); + } } } Some(FullscreenRestoreState::Sticky { .. }) => unreachable!(), @@ -3940,6 +3993,7 @@ impl Shell { previous: FloatingRestoreData { geometry: geo, output_size: set.output.geometry().size.as_logical(), + was_maximized: false, }, }); } else { @@ -4474,6 +4528,7 @@ impl Shell { state: FloatingRestoreData { geometry: from, output_size: workspace.output.geometry().size.as_logical(), + was_maximized: false, }, }), Some(from), diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index 7408a0a0..2b867a43 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -274,6 +274,7 @@ impl From for WorkspaceRestoreData { pub struct FloatingRestoreData { pub geometry: Rectangle, pub output_size: Size, + pub was_maximized: bool, } impl FloatingRestoreData { @@ -571,10 +572,13 @@ impl Workspace { } pub fn unmap_element(&mut self, mapped: &CosmicMapped) -> Option { - if mapped.maximized_state.lock().unwrap().is_some() { + 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 + } else { + false + }; self.focus_stack .0 @@ -594,18 +598,13 @@ impl Workspace { }); } - let was_maximized = - if let Some(floating_geometry) = self.floating_layer.unmap(&mapped, None) { - if mapped.maximized_state.lock().unwrap().is_none() { - return Some(WorkspaceRestoreData::Floating(Some(FloatingRestoreData { - geometry: floating_geometry, - output_size: self.output.geometry().size.as_logical(), - }))); - } - true - } else { - false - }; + 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, @@ -1012,37 +1011,37 @@ impl Workspace { }); } - let maybe_elem = self - .tiling_layer + let mapped = self .mapped() - .find(|(m, _)| m.windows().any(|(ref s, _)| s == surface)) - .map(|(s, _)| s.clone()); - if let Some(elem) = maybe_elem { - let was_maximized = self.floating_layer.unmap(&elem, None).is_some(); - let previous_state = self.tiling_layer.unmap(&elem, Some(to)).unwrap(); - elem.set_minimized(true); - return Some(MinimizedWindow::Tiling { - window: elem, - previous: TilingRestoreData { - state: previous_state, + .find(|m| m.windows().any(|(ref s, _)| s == surface)) + .cloned()?; + 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 + } else { + false + }; + + if let Some(geometry) = self.floating_layer.unmap(&mapped, Some(to)) { + mapped.set_minimized(true); + return Some(MinimizedWindow::Floating { + window: mapped, + previous: FloatingRestoreData { + geometry, + output_size: self.output.geometry().size.as_logical(), was_maximized, }, }); } - let maybe_elem = self - .floating_layer - .mapped() - .find(|m| m.windows().any(|(ref s, _)| s == surface)) - .cloned(); - if let Some(elem) = maybe_elem { - let geometry = self.floating_layer.unmap(&elem, Some(to)).unwrap(); - elem.set_minimized(true); - return Some(MinimizedWindow::Floating { - window: elem, - previous: FloatingRestoreData { - geometry, - output_size: self.output.geometry().size.as_logical(), + if let Ok(state) = self.tiling_layer.unmap(&mapped, Some(to)) { + mapped.set_minimized(true); + return Some(MinimizedWindow::Tiling { + window: mapped, + previous: TilingRestoreData { + state, + was_maximized, }, }); } @@ -1079,7 +1078,19 @@ impl Workspace { window.set_minimized(false); self.floating_layer - .remap_minimized(window, from, previous_position); + .remap_minimized(window.clone(), from, previous_position); + + if previous.was_maximized { + let geometry = self.floating_layer.element_geometry(&window).unwrap(); + let mut state = window.maximized_state.lock().unwrap(); + *state = Some(MaximizedState { + original_geometry: geometry, + original_layer: ManagedLayer::Floating, + }); + std::mem::drop(state); + self.floating_layer.map_maximized(window, geometry, false); + } + None } MinimizedWindow::Tiling { @@ -1098,16 +1109,29 @@ impl Workspace { if was_maximized { let previous_geometry = self.tiling_layer.element_geometry(&window).unwrap(); + let mut state = window.maximized_state.lock().unwrap(); + *state = Some(MaximizedState { + original_geometry: previous_geometry, + original_layer: ManagedLayer::Tiling, + }); + std::mem::drop(state); self.floating_layer .map_maximized(window, previous_geometry, true); } } else { + self.floating_layer.map(window.clone(), None); + let geometry = self.floating_layer.element_geometry(&window).unwrap(); + if was_maximized { + let mut state = window.maximized_state.lock().unwrap(); + *state = Some(MaximizedState { + original_geometry: geometry, + original_layer: ManagedLayer::Floating, + }); + std::mem::drop(state); self.floating_layer.map_maximized(window, from, true); } else { - self.floating_layer.map(window.clone(), None); // get the right animation - let geometry = self.floating_layer.element_geometry(&window).unwrap(); self.floating_layer .remap_minimized(window.clone(), from, geometry.loc); } diff --git a/src/wayland/handlers/toplevel_management.rs b/src/wayland/handlers/toplevel_management.rs index b329a5c6..91b16f9a 100644 --- a/src/wayland/handlers/toplevel_management.rs +++ b/src/wayland/handlers/toplevel_management.rs @@ -68,7 +68,10 @@ impl ToplevelManagementHandler for State { { for mapped in workspace .mapped() - .filter(|m| m.maximized_state.lock().unwrap().is_some()) + .filter(|m| { + m.maximized_state.lock().unwrap().is_some() + && !m.windows().any(|(ref w, _)| w == window) + }) .cloned() .collect::>() .into_iter()