diff --git a/data/keybindings.ron b/data/keybindings.ron index 986e827c..8f6e698c 100644 --- a/data/keybindings.ron +++ b/data/keybindings.ron @@ -14,6 +14,7 @@ (modifiers: [Super], key: "8"): Workspace(8), (modifiers: [Super], key: "9"): Workspace(9), (modifiers: [Super], key: "0"): LastWorkspace, + (modifiers: [Super], key: "p"): ToggleStickyVisibility, (modifiers: [Super, Shift], key: "1"): MoveToWorkspace(1), (modifiers: [Super, Shift], key: "2"): MoveToWorkspace(2), (modifiers: [Super, Shift], key: "3"): MoveToWorkspace(3), diff --git a/src/input/actions.rs b/src/input/actions.rs index a85cf8a0..73675133 100644 --- a/src/input/actions.rs +++ b/src/input/actions.rs @@ -182,6 +182,18 @@ impl State { ); } + Action::ToggleStickyVisibility => { + let mut shell = self.common.shell.write().unwrap(); + let sticky_visible = shell.workspaces.sticky_visible; + if sticky_visible { + shell.workspaces.sticky_visible = false; + shell.minimize_sticky(); + } else { + shell.workspaces.sticky_visible = true; + shell.unminimize_sticky(); + } + } + Action::NextWorkspace => { let next = to_next_workspace( &mut *self.common.shell.write().unwrap(), diff --git a/src/shell/mod.rs b/src/shell/mod.rs index c32f5cc5..bb0052b2 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -623,6 +623,7 @@ pub struct Workspaces { autotile: bool, autotile_behavior: TileBehavior, theme: cosmic::Theme, + pub sticky_visible: bool, } impl Workspaces { @@ -635,6 +636,7 @@ impl Workspaces { autotile: config.cosmic_conf.autotile, autotile_behavior: config.cosmic_conf.autotile_behavior, theme, + sticky_visible: true, } } @@ -3358,6 +3360,56 @@ impl Shell { } } + pub fn minimize_sticky(&mut self) { + for set in self.workspaces.sets.values_mut() { + let sticky_windows: Vec = set + .sticky_layer + .mapped() + .map(|mapped| mapped.clone()) + .collect(); + for sticky_window in sticky_windows { + let to = minimize_rectangle(&set.output, &sticky_window.active_window()); + let (window, position) = + set.sticky_layer.unmap_minimize(&sticky_window, to).unwrap(); + + set.minimized_windows.push(MinimizedWindow { + window, + previous_state: MinimizedState::Sticky { position }, + output_geo: set.output.geometry(), + fullscreen: None, + }); + } + } + } + + pub fn unminimize_sticky(&mut self) { + for set in self.workspaces.sets.values_mut() { + // All windows in Workspaceset are minimized + let minimized_windows: Vec = set.minimized_windows.drain(..).collect(); + for minimized_window in minimized_windows { + let from = + minimize_rectangle(&set.output, &minimized_window.window.active_window()); + if let MinimizedState::Sticky { mut position } = minimized_window.previous_state { + let current_output_size = set.output.geometry().size.as_logical(); + if current_output_size != minimized_window.output_geo.size.as_logical() { + position = Point::from(( + (position.x as f64 / minimized_window.output_geo.size.w as f64 + * current_output_size.w as f64) + .floor() as i32, + (position.y as f64 / minimized_window.output_geo.size.h as f64 + * current_output_size.h as f64) + .floor() as i32, + )) + }; + set.sticky_layer + .remap_minimized(minimized_window.window, from, position); + } else { + unreachable!("None sticky window in WorkspaceSet minimized_windows"); + } + } + } + } + pub fn maximize_request(&mut self, mapped: &CosmicMapped, seat: &Seat) { self.unminimize_request(mapped, seat); let (original_layer, floating_layer, original_geometry) = if let Some(set) = self