#[derive(Clone, Debug, Default)]
pub struct Monitor {
pub index: usize,
pub name: Option<String>,
pub position: (i32, i32),
pub size: (u32, u32),
pub scale_factor: f32,
pub refresh_rate_millihertz: Option<u32>,
pub is_primary: bool,
}
#[derive(Clone, Debug, Default)]
pub struct Monitors {
pub monitors: Vec<Monitor>,
pub primary_index: Option<usize>,
}
impl Monitor {
pub fn min_x(&self) -> i32 {
self.position.0
}
pub fn min_y(&self) -> i32 {
self.position.1
}
pub fn max_x(&self) -> i32 {
self.position.0 + self.size.0 as i32
}
pub fn max_y(&self) -> i32 {
self.position.1 + self.size.1 as i32
}
pub fn contains_point(&self, x: i32, y: i32) -> bool {
x >= self.min_x() && x < self.max_x() && y >= self.min_y() && y < self.max_y()
}
}
impl Monitors {
pub fn primary(&self) -> Option<&Monitor> {
self.primary_index
.and_then(|index| self.monitors.iter().find(|monitor| monitor.index == index))
}
pub fn at_index(&self, index: usize) -> Option<&Monitor> {
self.monitors.iter().find(|monitor| monitor.index == index)
}
pub fn at_position(&self, x: i32, y: i32) -> Option<&Monitor> {
self.monitors
.iter()
.find(|monitor| monitor.contains_point(x, y))
}
}
pub fn refresh_monitors_from_event_loop(
monitors: &mut Monitors,
event_loop: &winit::event_loop::ActiveEventLoop,
) {
monitors.monitors.clear();
let primary_handle = event_loop.primary_monitor();
let primary_handle_ref = primary_handle.as_ref();
let mut primary_index = None;
for (index, handle) in event_loop.available_monitors().enumerate() {
let position = handle.position();
let size = handle.size();
let is_primary = primary_handle_ref.is_some_and(|primary| primary == &handle);
if is_primary {
primary_index = Some(index);
}
monitors.monitors.push(Monitor {
index,
name: handle.name(),
position: (position.x, position.y),
size: (size.width, size.height),
scale_factor: handle.scale_factor() as f32,
refresh_rate_millihertz: handle.refresh_rate_millihertz(),
is_primary,
});
}
monitors.primary_index = primary_index;
}