#[derive(Debug, Clone)]
pub struct MonitorInfo {
pub id: String,
pub name: String,
pub position: (i32, i32),
pub size: (u32, u32),
pub work_area: (i32, i32, u32, u32),
pub scale_factor: f64,
pub is_primary: bool,
}
impl MonitorInfo {
pub fn logical_size(&self) -> (f64, f64) {
(f64::from(self.size.0) / self.scale_factor, f64::from(self.size.1) / self.scale_factor)
}
pub fn logical_work_area(&self) -> (f64, f64, f64, f64) {
(
f64::from(self.work_area.0) / self.scale_factor,
f64::from(self.work_area.1) / self.scale_factor,
f64::from(self.work_area.2) / self.scale_factor,
f64::from(self.work_area.3) / self.scale_factor,
)
}
}
pub trait MonitorManager: Send + Sync {
fn available_monitors(&self) -> Vec<MonitorInfo>;
fn primary_monitor(&self) -> Option<MonitorInfo> {
self.available_monitors().into_iter().find(|m| m.is_primary)
}
fn secondary_monitor(&self) -> Option<MonitorInfo> {
self.available_monitors().into_iter().find(|m| !m.is_primary)
}
fn find_by_name(&self, name: &str) -> Option<MonitorInfo> {
self.available_monitors().into_iter().find(|m| m.name == name)
}
fn find_by_selector(&self, selector: &str) -> Option<MonitorInfo> {
let monitors = self.available_monitors();
if let Ok(index) = selector.parse::<usize>()
&& index > 0
{
return monitors.get(index - 1).cloned();
}
monitors.iter().find(|m| m.name == selector || m.id == selector).cloned()
}
}