diff --git a/src/shell/mod.rs b/src/shell/mod.rs index bca087a5..13cc25cf 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -1179,26 +1179,23 @@ impl Shell { .refresh(&self.xdg_activation_state) } - pub fn visible_outputs_for_surface<'a>( - &'a self, - surface: &'a WlSurface, - ) -> impl Iterator + 'a { + pub fn visible_output_for_surface(&self, surface: &WlSurface) -> Option<&Output> { if let Some(session_lock) = &self.session_lock { - let output = session_lock + return session_lock .surfaces .iter() .find(|(_, v)| v.wl_surface() == surface) - .map(|(k, _)| k.clone()); - return Box::new(output.into_iter()) as Box>; + .map(|(k, _)| k); } - match self - .outputs() + self.outputs() + // layer map surface? .find(|o| { let map = layer_map_for_output(o); map.layer_for_surface(surface, WindowSurfaceType::ALL) .is_some() }) + // pending layer map surface? .or_else(|| { self.pending_layers.iter().find_map(|(l, output, _)| { let mut found = false; @@ -1209,13 +1206,10 @@ impl Shell { }); found.then_some(output) }) - }) { - Some(output) => { - Box::new(std::iter::once(output.clone())) as Box> - } - None => Box::new( - self.outputs() - .filter(|o| { + }) + // override redirect window? + .or_else(|| { + self.outputs().find(|o| { self.override_redirect_windows.iter().any(|or| { if or.wl_surface().as_ref() == Some(surface) { or.geometry() @@ -1227,15 +1221,24 @@ impl Shell { } }) }) - .cloned() - .chain(self.outputs().map(|o| self.active_space(o)).flat_map(|w| { - w.mapped() - .find(|e| e.has_surface(surface, WindowSurfaceType::ALL)) - .map(|_| w.output().clone()) - .into_iter() - })), - ), - } + }) + // sticky window ? + .or_else(|| { + self.outputs().find(|o| { + self.workspaces.sets[*o] + .sticky_layer + .mapped() + .any(|e| e.has_surface(surface, WindowSurfaceType::ALL)) + }) + }) + // normal window? + .or_else(|| { + self.outputs().find(|o| { + self.active_space(o) + .mapped() + .any(|e| e.has_surface(surface, WindowSurfaceType::ALL)) + }) + }) } pub fn workspace_for_surface(&self, surface: &WlSurface) -> Option<(WorkspaceHandle, Output)> { diff --git a/src/wayland/handlers/compositor.rs b/src/wayland/handlers/compositor.rs index e725c1fe..7e0a9c04 100644 --- a/src/wayland/handlers/compositor.rs +++ b/src/wayland/handlers/compositor.rs @@ -36,7 +36,7 @@ impl State { fn early_import_surface(&mut self, surface: &WlSurface) { let mut import_nodes = std::collections::HashSet::new(); let dh = &self.common.display_handle; - for output in self.common.shell.visible_outputs_for_surface(&surface) { + if let Some(output) = self.common.shell.visible_output_for_surface(&surface) { if let BackendData::Kms(ref mut kms_state) = &mut self.backend { if let Some(target) = kms_state.target_node_for_output(&output) { if import_nodes.insert(target) { @@ -261,7 +261,7 @@ impl CompositorHandler for State { let mut scheduled_sessions = self.schedule_workspace_sessions(surface); // schedule a new render - for output in self.common.shell.visible_outputs_for_surface(surface) { + if let Some(output) = self.common.shell.visible_output_for_surface(surface) { if let Some(sessions) = output.user_data().get::() { scheduled_sessions .get_or_insert_with(Vec::new) @@ -276,7 +276,7 @@ impl CompositorHandler for State { .iter() .filter(|(s, _)| match s.session_type() { SessionType::Output(o) | SessionType::Workspace(o, _) - if o == output => + if &o == output => { true } diff --git a/src/wayland/handlers/fractional_scale.rs b/src/wayland/handlers/fractional_scale.rs index a5b54224..c58e6ce1 100644 --- a/src/wayland/handlers/fractional_scale.rs +++ b/src/wayland/handlers/fractional_scale.rs @@ -41,8 +41,8 @@ impl FractionalScaleHandler for State { .or_else(|| { self.common .shell - .visible_outputs_for_surface(&surface) - .next() + .visible_output_for_surface(&surface) + .cloned() }) }) .unwrap_or_else(|| { diff --git a/src/wayland/handlers/xdg_shell/mod.rs b/src/wayland/handlers/xdg_shell/mod.rs index edbb65a5..1fd76ed3 100644 --- a/src/wayland/handlers/xdg_shell/mod.rs +++ b/src/wayland/handlers/xdg_shell/mod.rs @@ -315,12 +315,12 @@ impl XdgShellHandler for State { } fn toplevel_destroyed(&mut self, surface: ToplevelSurface) { - let outputs = self + let output = self .common .shell - .visible_outputs_for_surface(surface.wl_surface()) - .collect::>(); - for output in outputs.iter() { + .visible_output_for_surface(surface.wl_surface()) + .cloned(); + if let Some(output) = output.as_ref() { self.common.shell.refresh_active_space(output); } @@ -335,7 +335,7 @@ impl XdgShellHandler for State { // screencopy let mut scheduled_sessions = self.schedule_workspace_sessions(surface.wl_surface()); - for output in outputs.into_iter() { + if let Some(output) = output.as_ref() { if let Some(sessions) = output.user_data().get::() { scheduled_sessions .get_or_insert_with(Vec::new) @@ -349,7 +349,7 @@ impl XdgShellHandler for State { .iter() .filter(|(s, _)| match s.session_type() { SessionType::Output(o) | SessionType::Workspace(o, _) - if o == output => + if &o == output => { true } diff --git a/src/xwayland.rs b/src/xwayland.rs index 3d2015b2..98c15562 100644 --- a/src/xwayland.rs +++ b/src/xwayland.rs @@ -266,7 +266,9 @@ impl XwmHandler for State { let outputs = if let Some(wl_surface) = window.wl_surface() { self.common .shell - .visible_outputs_for_surface(&wl_surface) + .visible_output_for_surface(&wl_surface) + .into_iter() + .cloned() .collect::>() } else { self.common.shell.outputs().cloned().collect::>()