winit/
monitor.rs

1//! Types useful for interacting with a user's monitors.
2//!
3//! If you want to get basic information about a monitor, you can use the [`MonitorHandle`][monitor_handle]
4//! type. This is retrieved from one of the following methods, which return an iterator of
5//! [`MonitorHandle`][monitor_handle]:
6//! - [`EventLoopWindowTarget::available_monitors`][loop_get]
7//! - [`Window::available_monitors`][window_get].
8//!
9//! [monitor_handle]: crate::monitor::MonitorHandle
10//! [loop_get]: crate::event_loop::EventLoopWindowTarget::available_monitors
11//! [window_get]: crate::window::Window::available_monitors
12use crate::{
13    dpi::{PhysicalPosition, PhysicalSize},
14    platform_impl,
15};
16
17/// Describes a fullscreen video mode of a monitor.
18///
19/// Can be acquired with:
20/// - [`MonitorHandle::video_modes`][monitor_get].
21///
22/// [monitor_get]: crate::monitor::MonitorHandle::video_modes
23#[derive(Clone, PartialEq, Eq, Hash)]
24pub struct VideoMode {
25    pub(crate) video_mode: platform_impl::VideoMode,
26}
27
28impl std::fmt::Debug for VideoMode {
29    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30        self.video_mode.fmt(f)
31    }
32}
33
34impl PartialOrd for VideoMode {
35    fn partial_cmp(&self, other: &VideoMode) -> Option<std::cmp::Ordering> {
36        Some(self.cmp(other))
37    }
38}
39
40impl Ord for VideoMode {
41    fn cmp(&self, other: &VideoMode) -> std::cmp::Ordering {
42        // TODO: we can impl `Ord` for `PhysicalSize` once we switch from `f32`
43        // to `u32` there
44        let size: (u32, u32) = self.size().into();
45        let other_size: (u32, u32) = other.size().into();
46        self.monitor().cmp(&other.monitor()).then(
47            size.cmp(&other_size)
48                .then(
49                    self.refresh_rate()
50                        .cmp(&other.refresh_rate())
51                        .then(self.bit_depth().cmp(&other.bit_depth())),
52                )
53                .reverse(),
54        )
55    }
56}
57
58impl VideoMode {
59    /// Returns the resolution of this video mode.
60    #[inline]
61    pub fn size(&self) -> PhysicalSize<u32> {
62        self.video_mode.size()
63    }
64
65    /// Returns the bit depth of this video mode, as in how many bits you have
66    /// available per color. This is generally 24 bits or 32 bits on modern
67    /// systems, depending on whether the alpha channel is counted or not.
68    ///
69    /// ## Platform-specific
70    ///
71    /// - **Wayland:** Always returns 32.
72    /// - **iOS:** Always returns 32.
73    #[inline]
74    pub fn bit_depth(&self) -> u16 {
75        self.video_mode.bit_depth()
76    }
77
78    /// Returns the refresh rate of this video mode. **Note**: the returned
79    /// refresh rate is an integer approximation, and you shouldn't rely on this
80    /// value to be exact.
81    #[inline]
82    pub fn refresh_rate(&self) -> u16 {
83        self.video_mode.refresh_rate()
84    }
85
86    /// Returns the monitor that this video mode is valid for. Each monitor has
87    /// a separate set of valid video modes.
88    #[inline]
89    pub fn monitor(&self) -> MonitorHandle {
90        self.video_mode.monitor()
91    }
92}
93
94impl std::fmt::Display for VideoMode {
95    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
96        write!(
97            f,
98            "{}x{} @ {} Hz ({} bpp)",
99            self.size().width,
100            self.size().height,
101            self.refresh_rate(),
102            self.bit_depth()
103        )
104    }
105}
106
107/// Handle to a monitor.
108///
109/// Allows you to retrieve information about a given monitor and can be used in [`Window`] creation.
110///
111/// [`Window`]: crate::window::Window
112#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
113pub struct MonitorHandle {
114    pub(crate) inner: platform_impl::MonitorHandle,
115}
116
117impl MonitorHandle {
118    /// Returns a human-readable name of the monitor.
119    ///
120    /// Returns `None` if the monitor doesn't exist anymore.
121    ///
122    /// ## Platform-specific
123    ///
124    /// - **Web:** Always returns None
125    #[inline]
126    pub fn name(&self) -> Option<String> {
127        self.inner.name()
128    }
129
130    /// Returns the monitor's resolution.
131    ///
132    /// ## Platform-specific
133    ///
134    /// - **Web:** Always returns (0,0)
135    #[inline]
136    pub fn size(&self) -> PhysicalSize<u32> {
137        self.inner.size()
138    }
139
140    /// Returns the top-left corner position of the monitor relative to the larger full
141    /// screen area.
142    ///
143    /// ## Platform-specific
144    ///
145    /// - **Web:** Always returns (0,0)
146    #[inline]
147    pub fn position(&self) -> PhysicalPosition<i32> {
148        self.inner.position()
149    }
150
151    /// Returns the scale factor that can be used to map logical pixels to physical pixels, and vice versa.
152    ///
153    /// See the [`dpi`](crate::dpi) module for more information.
154    ///
155    /// ## Platform-specific
156    ///
157    /// - **X11:** Can be overridden using the `WINIT_X11_SCALE_FACTOR` environment variable.
158    /// - **Android:** Always returns 1.0.
159    /// - **Web:** Always returns 1.0
160    #[inline]
161    pub fn scale_factor(&self) -> f64 {
162        self.inner.scale_factor()
163    }
164
165    /// Returns all fullscreen video modes supported by this monitor.
166    ///
167    /// ## Platform-specific
168    ///
169    /// - **Web:** Always returns an empty iterator
170    #[inline]
171    pub fn video_modes(&self) -> impl Iterator<Item = VideoMode> {
172        self.inner.video_modes()
173    }
174}