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