1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use serde::{Deserialize, Serialize};
use winit::{AvailableMonitorsIter, EventsLoop, MonitorId, Window};
pub trait MonitorsAccess {
fn iter(&self) -> AvailableMonitorsIter;
fn primary(&self) -> MonitorId;
}
impl MonitorsAccess for EventsLoop {
fn iter(&self) -> AvailableMonitorsIter {
self.get_available_monitors()
}
fn primary(&self) -> MonitorId {
self.get_primary_monitor()
}
}
impl MonitorsAccess for Window {
fn iter(&self) -> AvailableMonitorsIter {
self.get_available_monitors()
}
fn primary(&self) -> MonitorId {
self.get_primary_monitor()
}
}
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct MonitorIdent(u16, String);
impl MonitorIdent {
pub fn from_primary(monitors: &impl MonitorsAccess) -> Self {
Self::from_monitor_id(monitors, monitors.primary())
.expect("Primary monitor not found in the list of all monitors")
}
pub fn from_monitor_id(monitors: &impl MonitorsAccess, monitor_id: MonitorId) -> Option<Self> {
#[cfg(target_os = "ios")]
use winit::ios::windows::MonitorIdExt;
#[cfg(target_os = "macos")]
use winit::os::macos::MonitorIdExt;
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))]
use winit::os::unix::MonitorIdExt;
#[cfg(target_os = "windows")]
use winit::os::windows::MonitorIdExt;
let native_id = monitor_id.native_id();
monitors
.iter()
.enumerate()
.find(|(_, m)| m.native_id() == native_id)
.and_then(|(i, m)| m.get_name().map(|name| Self(i as u16, name)))
}
pub fn monitor_id(&self, monitors: &impl MonitorsAccess) -> MonitorId {
monitors
.iter()
.enumerate()
.filter(|(_, m)| m.get_name().map(|n| n == self.1).unwrap_or(false))
.max_by_key(|(i, _)| (*i as i32 - i32::from(self.0)).abs() as u16)
.map(|(_, m)| m)
.unwrap_or_else(|| monitors.primary())
}
}