diff --git a/src/input/mod.rs b/src/input/mod.rs index 01c05373..145c8270 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -2039,9 +2039,9 @@ impl State { let current_output = seat.active_output(); let workspace = self.common.shell.active_space_mut(¤t_output); let focus_stack = workspace.focus_stack.get(seat); - let focused_window = focus_stack.last(); - if let Some(window) = focused_window.map(|f| f.active_window()) { - workspace.maximize_toggle(&window); + let focused_window = focus_stack.last().cloned(); + if let Some(window) = focused_window { + self.common.shell.maximize_toggle(&window); } } Action::Resizing(direction) => self.common.shell.set_resize_mode( diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 2174cf03..a46dcf0c 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -274,13 +274,7 @@ impl Program for CosmicWindowInternal { if let Some(mapped) = state.common.shell.element_for_wl_surface(&surface).cloned() { - if let Some(workspace) = state.common.shell.space_for_mut(&mapped) { - let (window, _) = mapped - .windows() - .find(|(w, _)| w.wl_surface().as_ref() == Some(&surface)) - .unwrap(); - workspace.maximize_toggle(&window) - } + state.common.shell.maximize_toggle(&mapped) } }); } diff --git a/src/shell/grabs/menu/default.rs b/src/shell/grabs/menu/default.rs index fd50af44..03107515 100644 --- a/src/shell/grabs/menu/default.rs +++ b/src/shell/grabs/menu/default.rs @@ -30,16 +30,6 @@ fn stack(state: &mut State, mapped: &CosmicMapped) { } } -fn maximize_toggle(state: &mut State, mapped: &CosmicMapped) { - if let Some(space) = state.common.shell.space_for_mut(mapped) { - if mapped.is_maximized(false) { - space.unmaximize_request(&mapped.active_window()); - } else { - space.maximize_request(&mapped.active_window()); - } - } -} - fn move_prev_workspace(state: &mut State, mapped: &CosmicMapped) { let seat = state.common.last_active_seat().clone(); let (current_handle, output) = { @@ -138,7 +128,7 @@ pub fn tab_items( .collect::>() .into_iter() { - workspace.unmaximize_request(&mapped.active_window()); + workspace.unmaximize_request(&mapped); } let focus_stack = workspace.focus_stack.get(&seat); workspace @@ -202,7 +192,8 @@ pub fn window_items( Some( Item::new(fl!("window-menu-maximize"), move |handle| { let mapped = maximize_clone.clone(); - let _ = handle.insert_idle(move |state| maximize_toggle(state, &mapped)); + let _ = + handle.insert_idle(move |state| state.common.shell.maximize_toggle(&mapped)); }) .shortcut(config.get_shortcut_for_action(&Action::Maximize)) .toggled(window.is_maximized(false)), diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 5dad7d26..bf57b772 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -71,7 +71,7 @@ use self::{ element::{ resize_indicator::{resize_indicator, ResizeIndicator}, swap_indicator::{swap_indicator, SwapIndicator}, - CosmicWindow, + CosmicWindow, MaximizedState, }, focus::target::{KeyboardFocusTarget, PointerFocusTarget}, grabs::{ @@ -2402,6 +2402,71 @@ impl Shell { } } + pub fn maximize_toggle(&mut self, window: &CosmicMapped) { + if window.is_maximized(true) { + self.unmaximize_request(window); + } else { + self.maximize_request(window); + } + } + + pub fn maximize_request(&mut self, mapped: &CosmicMapped) { + let (managed_layer, floating_layer) = if let Some(set) = self + .workspaces + .sets + .values_mut() + .find(|set| set.sticky_layer.mapped().any(|m| m == mapped)) + { + (ManagedLayer::Sticky, &mut set.sticky_layer) + } else if let Some(workspace) = self.space_for_mut(&mapped) { + let layer = if workspace.is_floating(&mapped) { + ManagedLayer::Floating + } else { + ManagedLayer::Tiling + }; + (layer, &mut workspace.floating_layer) + } else { + return; + }; + + let mut state = mapped.maximized_state.lock().unwrap(); + if state.is_none() { + *state = Some(MaximizedState { + original_geometry: floating_layer.element_geometry(&mapped).unwrap(), + original_layer: managed_layer, + }); + std::mem::drop(state); + floating_layer.map_maximized(mapped.clone()); + } + } + + pub fn unmaximize_request(&mut self, mapped: &CosmicMapped) -> Option> { + if let Some(set) = self + .workspaces + .sets + .values_mut() + .find(|set| set.sticky_layer.mapped().any(|m| m == mapped)) + { + let mut state = mapped.maximized_state.lock().unwrap(); + if let Some(state) = state.take() { + assert_eq!(state.original_layer, ManagedLayer::Sticky); + mapped.set_maximized(false); + set.sticky_layer.map_internal( + mapped.clone(), + Some(state.original_geometry.loc), + Some(state.original_geometry.size.as_logical()), + ); + Some(state.original_geometry.size.as_logical()) + } else { + None + } + } else if let Some(workspace) = self.space_for_mut(mapped) { + workspace.unmaximize_request(mapped) + } else { + None + } + } + pub fn resize_request( state: &mut State, surface: &WlSurface, diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index 4ebdfdbe..d5cfb43e 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -64,7 +64,6 @@ use super::{ element::{ resize_indicator::ResizeIndicator, stack::CosmicStackRenderElement, swap_indicator::SwapIndicator, window::CosmicWindowRenderElement, CosmicMapped, - MaximizedState, }, focus::{ target::{KeyboardFocusTarget, PointerFocusTarget, WindowGroup}, @@ -379,7 +378,7 @@ impl Workspace { 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.active_window()); + let _ = self.unmaximize_request(mapped); } let was_floating = self.floating_layer.unmap(&mapped); @@ -449,30 +448,7 @@ impl Workspace { self.floating_layer.refresh(); } - pub fn maximize_request(&mut self, window: &CosmicSurface) { - if self.fullscreen.is_some() { - return; - } - - if let Some(elem) = self.element_for_surface(window).cloned() { - let mut state = elem.maximized_state.lock().unwrap(); - if state.is_none() { - *state = Some(MaximizedState { - original_geometry: self.element_geometry(&elem).unwrap(), - original_layer: if self.is_floating(&elem) { - ManagedLayer::Floating - } else { - ManagedLayer::Tiling - }, - }); - std::mem::drop(state); - self.floating_layer.map_maximized(elem); - } - } - } - - pub fn unmaximize_request(&mut self, window: &CosmicSurface) -> Option> { - if let Some(elem) = self.element_for_surface(window).cloned() { + pub fn unmaximize_request(&mut self, elem: &CosmicMapped) -> Option> { let mut state = elem.maximized_state.lock().unwrap(); if let Some(state) = state.take() { match state.original_layer { @@ -484,10 +460,9 @@ impl Workspace { elem.set_geometry(state.original_geometry.to_global(&self.output)); elem.configure(); self.tiling_layer.recalculate(); - return self - .tiling_layer + self.tiling_layer .element_geometry(&elem) - .map(|geo| geo.size.as_logical()); + .map(|geo| geo.size.as_logical()) } ManagedLayer::Floating => { elem.set_maximized(false); @@ -496,12 +471,13 @@ impl Workspace { Some(state.original_geometry.loc), Some(state.original_geometry.size.as_logical()), ); - return Some(state.original_geometry.size.as_logical()); + Some(state.original_geometry.size.as_logical()) } + ManagedLayer::Sticky => unreachable!(), } - } - } + } else { None + } } pub fn fullscreen_request( @@ -611,14 +587,6 @@ impl Workspace { } } - pub fn maximize_toggle(&mut self, window: &CosmicSurface) { - if window.is_maximized(true) { - self.unmaximize_request(window); - } else { - self.maximize_request(window); - } - } - pub fn get_fullscreen(&self) -> Option<&CosmicSurface> { self.fullscreen .as_ref() @@ -710,7 +678,7 @@ impl Workspace { pub fn toggle_floating_window(&mut self, seat: &Seat, window: &CosmicMapped) { if self.tiling_enabled { if window.is_maximized(false) { - self.unmaximize_request(&window.active_window()); + self.unmaximize_request(window); } if self.tiling_layer.mapped().any(|(_, m, _)| m == window) { self.tiling_layer.unmap(window); diff --git a/src/wayland/handlers/xdg_shell/mod.rs b/src/wayland/handlers/xdg_shell/mod.rs index d67f8a36..348cf3b1 100644 --- a/src/wayland/handlers/xdg_shell/mod.rs +++ b/src/wayland/handlers/xdg_shell/mod.rs @@ -169,13 +169,7 @@ impl XdgShellHandler for State { .element_for_wl_surface(surface.wl_surface()) .cloned() { - if let Some(workspace) = self.common.shell.space_for_mut(&mapped) { - let (window, _) = mapped - .windows() - .find(|(w, _)| w.wl_surface().as_ref() == Some(surface.wl_surface())) - .unwrap(); - workspace.maximize_request(&window) - } + self.common.shell.maximize_request(&mapped) } } @@ -186,13 +180,7 @@ impl XdgShellHandler for State { .element_for_wl_surface(surface.wl_surface()) .cloned() { - if let Some(workspace) = self.common.shell.space_for_mut(&mapped) { - let (window, _) = mapped - .windows() - .find(|(w, _)| w.wl_surface().as_ref() == Some(surface.wl_surface())) - .unwrap(); - workspace.unmaximize_request(&window); - } + self.common.shell.unmaximize_request(&mapped); } } diff --git a/src/xwayland.rs b/src/xwayland.rs index 5dcc4c5d..7026aa44 100644 --- a/src/xwayland.rs +++ b/src/xwayland.rs @@ -426,20 +426,14 @@ impl XwmHandler for State { fn maximize_request(&mut self, _xwm: XwmId, window: X11Surface) { let surface = CosmicSurface::X11(window); if let Some(mapped) = self.common.shell.element_for_surface(&surface).cloned() { - if let Some(workspace) = self.common.shell.space_for_mut(&mapped) { - let (window, _) = mapped.windows().find(|(w, _)| w == &surface).unwrap(); - workspace.maximize_request(&window); - } + self.common.shell.maximize_request(&mapped); } } fn unmaximize_request(&mut self, _xwm: XwmId, window: X11Surface) { let surface = CosmicSurface::X11(window); if let Some(mapped) = self.common.shell.element_for_surface(&surface).cloned() { - if let Some(workspace) = self.common.shell.space_for_mut(&mapped) { - let (window, _) = mapped.windows().find(|(w, _)| w == &surface).unwrap(); - workspace.unmaximize_request(&window); - } + self.common.shell.unmaximize_request(&mapped); } }