rio_window/
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 {
81            inner: self.video_mode.monitor(),
82        }
83    }
84}
85
86impl std::fmt::Display for VideoModeHandle {
87    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88        write!(
89            f,
90            "{}x{} @ {} mHz ({} bpp)",
91            self.size().width,
92            self.size().height,
93            self.refresh_rate_millihertz(),
94            self.bit_depth()
95        )
96    }
97}
98
99/// Handle to a monitor.
100///
101/// Allows you to retrieve information about a given monitor and can be used in [`Window`] creation.
102///
103/// [`Window`]: crate::window::Window
104#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
105pub struct MonitorHandle {
106    pub(crate) inner: platform_impl::MonitorHandle,
107}
108
109impl MonitorHandle {
110    /// Returns a human-readable name of the monitor.
111    ///
112    /// Returns `None` if the monitor doesn't exist anymore.
113    #[inline]
114    pub fn name(&self) -> Option<String> {
115        self.inner.name()
116    }
117
118    /// Returns the monitor's resolution.
119    #[inline]
120    pub fn size(&self) -> PhysicalSize<u32> {
121        self.inner.size()
122    }
123
124    /// Returns the top-left corner position of the monitor relative to the larger full
125    /// screen area.
126    #[inline]
127    pub fn position(&self) -> PhysicalPosition<i32> {
128        self.inner.position()
129    }
130
131    /// The monitor refresh rate used by the system.
132    ///
133    /// Return `Some` if succeed, or `None` if failed, which usually happens when the monitor
134    /// the window is on is removed.
135    ///
136    /// When using exclusive fullscreen, the refresh rate of the [`VideoModeHandle`] that was
137    /// used to enter fullscreen should be used instead.
138    #[inline]
139    pub fn refresh_rate_millihertz(&self) -> Option<u32> {
140        self.inner.refresh_rate_millihertz()
141    }
142
143    /// Returns the scale factor of the underlying monitor. To map logical pixels to physical
144    /// pixels and vice versa, use [`Window::scale_factor`].
145    ///
146    /// See the [`dpi`] module for more information.
147    ///
148    /// ## Platform-specific
149    ///
150    /// - **X11:** Can be overridden using the `WINIT_X11_SCALE_FACTOR` environment variable.
151    /// - **Wayland:** May differ from [`Window::scale_factor`].
152    /// - **Android:** Always returns 1.0.
153    ///
154    /// [`Window::scale_factor`]: crate::window::Window::scale_factor
155    #[inline]
156    pub fn scale_factor(&self) -> f64 {
157        self.inner.scale_factor()
158    }
159
160    /// Returns all fullscreen video modes supported by this monitor.
161    ///
162    /// ## Platform-specific
163    ///
164    /// - **Web:** Always returns an empty iterator
165    #[inline]
166    pub fn video_modes(&self) -> impl Iterator<Item = VideoModeHandle> {
167        self.inner
168            .video_modes()
169            .map(|video_mode| VideoModeHandle { video_mode })
170    }
171}