diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index 2091b6a8..824c0e24 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -136,13 +136,22 @@ impl FloatingLayout { } pub fn unmap_window(&mut self, space: &mut Space, window: &Window) { - if let Some(location) = space.window_location(window) { - let user_data = window.user_data(); - user_data.insert_if_missing(|| WindowUserData::default()); - user_data.get::().unwrap().lock().unwrap().last_geometry = Rectangle::from_loc_and_size( - location, - window.geometry().size, - ); + #[allow(irrefutable_let_patterns)] + let is_maximized = match &window.toplevel() { + Kind::Xdg(surface) => surface.with_pending_state(|state| { + state.states.contains(XdgState::Maximized) + }) + }; + + if !is_maximized { + if let Some(location) = space.window_location(window) { + let user_data = window.user_data(); + user_data.insert_if_missing(|| WindowUserData::default()); + user_data.get::().unwrap().lock().unwrap().last_geometry = Rectangle::from_loc_and_size( + location, + window.geometry().size, + ); + } } space.unmap_window(window); @@ -153,7 +162,16 @@ impl FloatingLayout { pub fn maximize_request(&mut self, space: &mut Space, window: &Window, output: &Output) { let layers = layer_map_for_output(&output); let geometry = layers.non_exclusive_zone(); - + + if let Some(location) = space.window_location(window) { + let user_data = window.user_data(); + user_data.insert_if_missing(|| WindowUserData::default()); + user_data.get::().unwrap().lock().unwrap().last_geometry = Rectangle::from_loc_and_size( + location, + window.geometry().size, + ); + } + space.map_window( &window, (geometry.loc.x, geometry.loc.y), @@ -170,6 +188,27 @@ impl FloatingLayout { } } + pub fn unmaximize_request(&mut self, space: &mut Space, window: &Window) { + let last_geometry = window.user_data().get::().map(|u| u.lock().unwrap().last_geometry); + match window.toplevel() { + Kind::Xdg(toplevel) => { + toplevel.with_pending_state(|state| { + state.states.unset(XdgState::Maximized); + state.size = last_geometry.map(|g| g.size); + }); + toplevel.send_configure(); + } + } + if let Some(last_location) = last_geometry.map(|g| g.loc) { + space.map_window( + &window, + last_location, + FLOATING_INDEX, + true, + ); + } + } + pub fn move_request( &mut self, space: &mut Space, diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index 5a7617ea..fc2f9933 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -69,6 +69,16 @@ impl Workspace { .maximize_request(&mut self.space, window, output); } } + + pub fn unmaximize_request(&mut self, window: &Window) { + if self.fullscreen.values().any(|w| w == window) { + return self.unfullscreen_request(window); + } + if self.floating_layer.windows.contains(window) { + self.floating_layer + .unmaximize_request(&mut self.space, window); + } + } pub fn move_request( &mut self, diff --git a/src/wayland/handlers/xdg_shell/mod.rs b/src/wayland/handlers/xdg_shell/mod.rs index ab646406..70934c7c 100644 --- a/src/wayland/handlers/xdg_shell/mod.rs +++ b/src/wayland/handlers/xdg_shell/mod.rs @@ -226,11 +226,16 @@ impl XdgShellHandler for State { } fn unmaximize_request(&mut self, _dh: &DisplayHandle, surface: ToplevelSurface) { - surface.with_pending_state(|state| { - state.states.unset(xdg_toplevel::State::Maximized); - state.size = None; - }); - surface.send_configure(); + let surface = surface.wl_surface(); + + if let Some(workspace) = self.common.shell.space_for_surface_mut(surface) { + let window = workspace + .space + .window_for_surface(surface, WindowSurfaceType::TOPLEVEL) + .unwrap() + .clone(); + workspace.unmaximize_request(&window) + } } fn fullscreen_request(