shell/workspace: Store edid in output stack

Matches by edid where present, or by connector name if there is no edid
information.
This commit is contained in:
Ian Douglas Scott 2025-03-26 12:54:46 -07:00 committed by Victoria Brekenfeld
parent 75aab6e282
commit 70ed075e80

View file

@ -4,6 +4,7 @@ use crate::{
element::{AsGlowRenderer, FromGlesError}, element::{AsGlowRenderer, FromGlesError},
BackdropShader, BackdropShader,
}, },
config::EdidProduct,
shell::{ shell::{
layout::{floating::FloatingLayout, tiling::TilingLayout}, layout::{floating::FloatingLayout, tiling::TilingLayout},
OverviewMode, ANIMATION_DURATION, OverviewMode, ANIMATION_DURATION,
@ -73,6 +74,25 @@ use super::{
const FULLSCREEN_ANIMATION_DURATION: Duration = Duration::from_millis(200); const FULLSCREEN_ANIMATION_DURATION: Duration = Duration::from_millis(200);
#[derive(Debug, Clone, PartialEq, Eq)]
struct OutputMatch {
name: String,
edid: Option<EdidProduct>,
}
impl OutputMatch {
fn for_output(output: &Output) -> Self {
Self {
name: output.name(),
edid: output.edid().cloned(),
}
}
fn matches(&self, output: &Output) -> bool {
self.edid.as_ref() == output.edid() && (self.edid.is_some() || self.name == output.name())
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct Workspace { pub struct Workspace {
pub output: Output, pub output: Output,
@ -85,7 +105,7 @@ pub struct Workspace {
pub handle: WorkspaceHandle, pub handle: WorkspaceHandle,
pub focus_stack: FocusStacks, pub focus_stack: FocusStacks,
pub screencopy: ScreencopySessions, pub screencopy: ScreencopySessions,
output_stack: VecDeque<String>, output_stack: VecDeque<OutputMatch>,
pub(super) backdrop_id: Id, pub(super) backdrop_id: Id,
pub dirty: AtomicBool, pub dirty: AtomicBool,
} }
@ -241,7 +261,7 @@ impl Workspace {
) -> Workspace { ) -> Workspace {
let tiling_layer = TilingLayout::new(theme.clone(), &output); let tiling_layer = TilingLayout::new(theme.clone(), &output);
let floating_layer = FloatingLayout::new(theme, &output); let floating_layer = FloatingLayout::new(theme, &output);
let output_name = output.name(); let output_match = OutputMatch::for_output(&output);
Workspace { Workspace {
output, output,
@ -255,7 +275,7 @@ impl Workspace {
screencopy: ScreencopySessions::default(), screencopy: ScreencopySessions::default(),
output_stack: { output_stack: {
let mut queue = VecDeque::new(); let mut queue = VecDeque::new();
queue.push_back(output_name); queue.push_back(output_match);
queue queue
}, },
backdrop_id: Id::new(), backdrop_id: Id::new(),
@ -383,21 +403,16 @@ impl Workspace {
if explicit { if explicit {
self.output_stack.clear(); self.output_stack.clear();
} }
let output_name = output.name(); if let Some(pos) = self.output_stack.iter().position(|i| i.matches(output)) {
if let Some(pos) = self
.output_stack
.iter()
.position(|name| name == &output_name)
{
self.output_stack.truncate(pos + 1); self.output_stack.truncate(pos + 1);
} else { } else {
self.output_stack.push_back(output.name()); self.output_stack.push_back(OutputMatch::for_output(output));
} }
self.output = output.clone(); self.output = output.clone();
} }
pub fn prefers_output(&self, output: &Output) -> bool { pub fn prefers_output(&self, output: &Output) -> bool {
self.output_stack.contains(&output.name()) self.output_stack.iter().any(|i| i.matches(output))
} }
pub fn unmap(&mut self, mapped: &CosmicMapped) -> Option<ManagedState> { pub fn unmap(&mut self, mapped: &CosmicMapped) -> Option<ManagedState> {