diff --git a/src/shell/element/mod.rs b/src/shell/element/mod.rs index d4743b7f..c7e799be 100644 --- a/src/shell/element/mod.rs +++ b/src/shell/element/mod.rs @@ -430,6 +430,10 @@ impl CosmicMapped { } } + pub fn is_sticky(&self) -> bool { + self.active_window().is_sticky() + } + pub fn pending_size(&self) -> Option> { match &self.element { CosmicMappedInternal::Stack(s) => s.pending_size(), diff --git a/src/shell/focus/mod.rs b/src/shell/focus/mod.rs index dcfd55de..8b2348eb 100644 --- a/src/shell/focus/mod.rs +++ b/src/shell/focus/mod.rs @@ -255,8 +255,17 @@ impl Shell { let workspace = if let Some(workspace) = workspace { self.workspaces.space_for_handle_mut(&workspace.0).unwrap() } else { - //should this be the active output or the focused output? - self.active_space_mut(&seat.focused_or_active_output()) + let output = match &target { + FocusTarget::Window(mapped) => self + .workspaces + .sets + .iter() + .find(|(_, set)| set.sticky_layer.mapped().any(|m| m == mapped)) + .map(|(output, _)| output.clone()), + FocusTarget::Fullscreen(_) => None, + }; + + self.active_space_mut(&output.unwrap_or_else(|| seat.active_output())) .unwrap() }; diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 8439b13f..10b40b59 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -516,6 +516,12 @@ impl WorkspaceSet { } } + fn refresh_focus_stacks(&mut self) { + for workspace in &mut self.workspaces { + workspace.refresh_focus_stack(); + } + } + fn activate( &mut self, idx: usize, @@ -620,6 +626,7 @@ impl WorkspaceSet { self.workspaces[self.active].refresh(); } self.sticky_layer.refresh(); + self.refresh_focus_stacks(); } fn add_empty_workspace(&mut self, state: &mut WorkspaceUpdateGuard) { diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index 84a020ff..fd63dcb1 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -526,10 +526,16 @@ impl Workspace { .mapped() .chain(self.tiling_layer.mapped().map(|(w, _)| w)) .chain(move_mapped.iter()) + .chain( + self.minimized_windows + .iter() + .flat_map(MinimizedWindow::mapped), + ) }; stack.retain(|w| match w { FocusTarget::Fullscreen(s) => fullscreen_surfaces.contains(&s), - FocusTarget::Window(w) => mapped().any(|m| w == m), + // Sticky windows live in the `WorkspaceSet` but are shown on whichever workspace is current + FocusTarget::Window(w) => w.is_sticky() || mapped().any(|m| w == m), }); } } @@ -1767,13 +1773,17 @@ impl Workspace { self.floating_layer.render( renderer, - focused.as_ref().and_then(|target| { - if let FocusTarget::Window(mapped) = target { - Some(mapped) - } else { - None - } - }), + render_focus + .then(|| { + focused.as_ref().and_then(|target| { + if let FocusTarget::Window(mapped) = target { + Some(mapped) + } else { + None + } + }) + }) + .flatten(), resize_indicator.clone(), indicator_thickness, alpha,