shell: refactor single visible_output

This commit is contained in:
Victoria Brekenfeld 2023-12-20 19:58:43 +00:00 committed by Victoria Brekenfeld
parent 414cbfef2d
commit d503e44ca8
5 changed files with 42 additions and 37 deletions

View file

@ -1179,26 +1179,23 @@ impl Shell {
.refresh(&self.xdg_activation_state) .refresh(&self.xdg_activation_state)
} }
pub fn visible_outputs_for_surface<'a>( pub fn visible_output_for_surface(&self, surface: &WlSurface) -> Option<&Output> {
&'a self,
surface: &'a WlSurface,
) -> impl Iterator<Item = Output> + 'a {
if let Some(session_lock) = &self.session_lock { if let Some(session_lock) = &self.session_lock {
let output = session_lock return session_lock
.surfaces .surfaces
.iter() .iter()
.find(|(_, v)| v.wl_surface() == surface) .find(|(_, v)| v.wl_surface() == surface)
.map(|(k, _)| k.clone()); .map(|(k, _)| k);
return Box::new(output.into_iter()) as Box<dyn Iterator<Item = Output>>;
} }
match self self.outputs()
.outputs() // layer map surface?
.find(|o| { .find(|o| {
let map = layer_map_for_output(o); let map = layer_map_for_output(o);
map.layer_for_surface(surface, WindowSurfaceType::ALL) map.layer_for_surface(surface, WindowSurfaceType::ALL)
.is_some() .is_some()
}) })
// pending layer map surface?
.or_else(|| { .or_else(|| {
self.pending_layers.iter().find_map(|(l, output, _)| { self.pending_layers.iter().find_map(|(l, output, _)| {
let mut found = false; let mut found = false;
@ -1209,13 +1206,10 @@ impl Shell {
}); });
found.then_some(output) found.then_some(output)
}) })
}) { })
Some(output) => { // override redirect window?
Box::new(std::iter::once(output.clone())) as Box<dyn Iterator<Item = Output>> .or_else(|| {
} self.outputs().find(|o| {
None => Box::new(
self.outputs()
.filter(|o| {
self.override_redirect_windows.iter().any(|or| { self.override_redirect_windows.iter().any(|or| {
if or.wl_surface().as_ref() == Some(surface) { if or.wl_surface().as_ref() == Some(surface) {
or.geometry() or.geometry()
@ -1227,15 +1221,24 @@ impl Shell {
} }
}) })
}) })
.cloned() })
.chain(self.outputs().map(|o| self.active_space(o)).flat_map(|w| { // sticky window ?
w.mapped() .or_else(|| {
.find(|e| e.has_surface(surface, WindowSurfaceType::ALL)) self.outputs().find(|o| {
.map(|_| w.output().clone()) self.workspaces.sets[*o]
.into_iter() .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)> { pub fn workspace_for_surface(&self, surface: &WlSurface) -> Option<(WorkspaceHandle, Output)> {

View file

@ -36,7 +36,7 @@ impl State {
fn early_import_surface(&mut self, surface: &WlSurface) { fn early_import_surface(&mut self, surface: &WlSurface) {
let mut import_nodes = std::collections::HashSet::new(); let mut import_nodes = std::collections::HashSet::new();
let dh = &self.common.display_handle; 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 BackendData::Kms(ref mut kms_state) = &mut self.backend {
if let Some(target) = kms_state.target_node_for_output(&output) { if let Some(target) = kms_state.target_node_for_output(&output) {
if import_nodes.insert(target) { if import_nodes.insert(target) {
@ -261,7 +261,7 @@ impl CompositorHandler for State {
let mut scheduled_sessions = self.schedule_workspace_sessions(surface); let mut scheduled_sessions = self.schedule_workspace_sessions(surface);
// schedule a new render // 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::<PendingScreencopyBuffers>() { if let Some(sessions) = output.user_data().get::<PendingScreencopyBuffers>() {
scheduled_sessions scheduled_sessions
.get_or_insert_with(Vec::new) .get_or_insert_with(Vec::new)
@ -276,7 +276,7 @@ impl CompositorHandler for State {
.iter() .iter()
.filter(|(s, _)| match s.session_type() { .filter(|(s, _)| match s.session_type() {
SessionType::Output(o) | SessionType::Workspace(o, _) SessionType::Output(o) | SessionType::Workspace(o, _)
if o == output => if &o == output =>
{ {
true true
} }

View file

@ -41,8 +41,8 @@ impl FractionalScaleHandler for State {
.or_else(|| { .or_else(|| {
self.common self.common
.shell .shell
.visible_outputs_for_surface(&surface) .visible_output_for_surface(&surface)
.next() .cloned()
}) })
}) })
.unwrap_or_else(|| { .unwrap_or_else(|| {

View file

@ -315,12 +315,12 @@ impl XdgShellHandler for State {
} }
fn toplevel_destroyed(&mut self, surface: ToplevelSurface) { fn toplevel_destroyed(&mut self, surface: ToplevelSurface) {
let outputs = self let output = self
.common .common
.shell .shell
.visible_outputs_for_surface(surface.wl_surface()) .visible_output_for_surface(surface.wl_surface())
.collect::<Vec<_>>(); .cloned();
for output in outputs.iter() { if let Some(output) = output.as_ref() {
self.common.shell.refresh_active_space(output); self.common.shell.refresh_active_space(output);
} }
@ -335,7 +335,7 @@ impl XdgShellHandler for State {
// screencopy // screencopy
let mut scheduled_sessions = self.schedule_workspace_sessions(surface.wl_surface()); 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::<PendingScreencopyBuffers>() { if let Some(sessions) = output.user_data().get::<PendingScreencopyBuffers>() {
scheduled_sessions scheduled_sessions
.get_or_insert_with(Vec::new) .get_or_insert_with(Vec::new)
@ -349,7 +349,7 @@ impl XdgShellHandler for State {
.iter() .iter()
.filter(|(s, _)| match s.session_type() { .filter(|(s, _)| match s.session_type() {
SessionType::Output(o) | SessionType::Workspace(o, _) SessionType::Output(o) | SessionType::Workspace(o, _)
if o == output => if &o == output =>
{ {
true true
} }

View file

@ -266,7 +266,9 @@ impl XwmHandler for State {
let outputs = if let Some(wl_surface) = window.wl_surface() { let outputs = if let Some(wl_surface) = window.wl_surface() {
self.common self.common
.shell .shell
.visible_outputs_for_surface(&wl_surface) .visible_output_for_surface(&wl_surface)
.into_iter()
.cloned()
.collect::<Vec<_>>() .collect::<Vec<_>>()
} else { } else {
self.common.shell.outputs().cloned().collect::<Vec<_>>() self.common.shell.outputs().cloned().collect::<Vec<_>>()