fix: restore snapped windows as snapped after maximize/minimize

This commit is contained in:
Hojjat 2026-04-21 15:52:26 -06:00 committed by Victoria Brekenfeld
parent 7c02df250e
commit b5186ef21a
4 changed files with 42 additions and 7 deletions

View file

@ -82,10 +82,11 @@ space_elements! {
Stack=CosmicStack,
}
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Copy)]
pub struct MaximizedState {
pub original_geometry: Rectangle<i32, Local>,
pub original_layer: ManagedLayer,
pub original_snapped: Option<TiledCorners>,
}
#[derive(Clone)]

View file

@ -385,11 +385,13 @@ impl FloatingLayout {
} else {
self.animations.remove(&mapped);
}
if mapped.floating_tiled.lock().unwrap().take().is_some()
// Restore to the corner this was snapped to if any
let snapped = mapped.floating_tiled.lock().unwrap().take();
if let Some(snapped) = snapped
&& let Some(state) = mapped.maximized_state.lock().unwrap().as_mut()
&& let Some(real_old_geo) = *mapped.last_geometry.lock().unwrap()
&& state.original_snapped.is_none()
{
state.original_geometry = real_old_geo;
state.original_snapped = Some(snapped);
};
self.space
.map_element(mapped, geometry.loc.as_logical(), true);
@ -1198,6 +1200,7 @@ impl FloatingLayout {
*maximized_state = Some(MaximizedState {
original_geometry: start_rectangle,
original_layer: layer,
original_snapped: None,
});
std::mem::drop(maximized_state);

View file

@ -2591,6 +2591,7 @@ impl Shell {
*state = Some(MaximizedState {
original_geometry: geometry,
original_layer: ManagedLayer::Floating,
original_snapped: was_snapped,
});
std::mem::drop(state);
workspace.floating_layer.map_maximized(
@ -2625,6 +2626,7 @@ impl Shell {
*state = Some(MaximizedState {
original_geometry: previous_geometry,
original_layer: ManagedLayer::Tiling,
original_snapped: None,
});
std::mem::drop(state);
workspace.floating_layer.map_maximized(
@ -2647,6 +2649,7 @@ impl Shell {
*state = Some(MaximizedState {
original_geometry: geometry,
original_layer: ManagedLayer::Floating,
original_snapped: None,
});
std::mem::drop(state);
workspace.floating_layer.map_maximized(
@ -3372,6 +3375,7 @@ impl Shell {
*mapped.maximized_state.lock().unwrap() = Some(MaximizedState {
original_geometry: geometry,
original_layer: ManagedLayer::Floating,
original_snapped: was_snapped,
});
to_workspace
.floating_layer
@ -4281,6 +4285,7 @@ impl Shell {
*state = Some(MaximizedState {
original_geometry,
original_layer,
original_snapped: None,
});
std::mem::drop(state);
floating_layer.map_maximized(mapped.clone(), original_geometry, animate);
@ -4304,7 +4309,7 @@ impl Shell {
.iter_mut()
.find(|m| m.mapped().is_some_and(|m| m == mapped))
{
minimized.unmaximize(state.original_geometry);
minimized.unmaximize(state.original_geometry, state.original_snapped);
} else {
mapped.set_maximized(false);
set.sticky_layer.map_internal(
@ -4313,6 +4318,10 @@ impl Shell {
Some(state.original_geometry.size.as_logical()),
None,
);
// Re-apply the snap if the window was snapped when it was maximized.
if let Some(corners) = state.original_snapped {
set.sticky_layer.snap_to_corner(mapped, &corners);
}
}
Some(state.original_geometry.size.as_logical())
} else {
@ -4589,11 +4598,13 @@ impl Shell {
if let Some(MaximizedState {
original_geometry,
original_layer: _,
original_snapped,
}) = *state
{
*state = Some(MaximizedState {
original_geometry,
original_layer: ManagedLayer::Sticky,
original_snapped,
});
std::mem::drop(state);
set.workspaces[set.active].floating_layer.map_maximized(
@ -4637,11 +4648,13 @@ impl Shell {
if let Some(MaximizedState {
original_geometry,
original_layer: _,
original_snapped,
}) = *state
{
*state = Some(MaximizedState {
original_geometry,
original_layer: previous_layer,
original_snapped,
});
std::mem::drop(state);
workspace

View file

@ -182,7 +182,11 @@ impl MinimizedWindow {
}
}
pub fn unmaximize(&mut self, original_geometry: Rectangle<i32, Local>) {
pub fn unmaximize(
&mut self,
original_geometry: Rectangle<i32, Local>,
original_snapped: Option<TiledCorners>,
) {
match self {
MinimizedWindow::Fullscreen { .. } => {}
MinimizedWindow::Tiling {
@ -196,6 +200,7 @@ impl MinimizedWindow {
window, previous, ..
} => {
previous.geometry = original_geometry;
previous.was_snapped = original_snapped;
window.set_maximized(false);
window.configure();
}
@ -972,7 +977,7 @@ impl Workspace {
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);
minimized.unmaximize(state.original_geometry, state.original_snapped);
Some(state.original_geometry)
} else {
match state.original_layer {
@ -998,6 +1003,10 @@ impl Workspace {
use_geometry.then_some(state.original_geometry.size.as_logical()),
None,
);
// Re-apply the snap if the window was snapped before maximizing
if let Some(corners) = state.original_snapped {
self.floating_layer.snap_to_corner(elem, &corners);
}
Some(state.original_geometry)
}
}
@ -1052,6 +1061,7 @@ impl Workspace {
let was_maximized = if let Some(MaximizedState {
original_geometry,
original_layer,
original_snapped,
}) = mapped.maximized_state.lock().unwrap().take()
{
// we need to do this manually instead of calling `self.unmaximize_request`
@ -1064,6 +1074,10 @@ impl Workspace {
}
mapped.set_geometry(original_geometry.to_global(&self.output));
mapped.set_maximized(false);
// Restore the snap marker to lett unminimize re-apply it.
if let Some(corners) = original_snapped {
*mapped.floating_tiled.lock().unwrap() = Some(corners);
}
Some(original_geometry)
} else {
None
@ -1138,6 +1152,7 @@ impl Workspace {
*state = Some(MaximizedState {
original_geometry: geometry,
original_layer: ManagedLayer::Floating,
original_snapped: previous.was_snapped,
});
std::mem::drop(state);
self.floating_layer.map_maximized(window, geometry, true);
@ -1171,6 +1186,7 @@ impl Workspace {
*state = Some(MaximizedState {
original_geometry: previous_geometry,
original_layer: ManagedLayer::Tiling,
original_snapped: None,
});
std::mem::drop(state);
self.floating_layer.map_maximized(window, from, true);
@ -1187,6 +1203,7 @@ impl Workspace {
*state = Some(MaximizedState {
original_geometry: geometry,
original_layer: ManagedLayer::Tiling,
original_snapped: None,
});
std::mem::drop(state);
self.floating_layer.map_maximized(window, from, true);
@ -1393,6 +1410,7 @@ impl Workspace {
*state = Some(MaximizedState {
original_geometry,
original_layer,
original_snapped: None,
});
std::mem::drop(state);