diff --git a/examples/window.rs b/examples/window.rs index b1862da4..0b9b1ac7 100644 --- a/examples/window.rs +++ b/examples/window.rs @@ -302,15 +302,17 @@ impl Application { info!("{intro}: [no name]"); } - let PhysicalSize { width, height } = monitor.size(); - info!( - " Current mode: {width}x{height}{}", - if let Some(m_hz) = monitor.refresh_rate_millihertz() { - format!(" @ {}.{} Hz", m_hz / 1000, m_hz % 1000) - } else { - String::new() - } - ); + if let Some(current_mode) = monitor.current_video_mode() { + let PhysicalSize { width, height } = current_mode.size(); + info!( + " Current mode: {width}x{height}{}", + if let Some(m_hz) = current_mode.refresh_rate_millihertz() { + format!(" @ {}.{} Hz", m_hz / 1000, m_hz % 1000) + } else { + String::new() + } + ); + } let PhysicalPosition { x, y } = monitor.position(); info!(" Position: {x},{y}"); @@ -321,8 +323,12 @@ impl Application { for mode in monitor.video_modes() { let PhysicalSize { width, height } = mode.size(); let bits = mode.bit_depth(); - let m_hz = mode.refresh_rate_millihertz(); - info!(" {width}x{height}x{bits} @ {}.{} Hz", m_hz / 1000, m_hz % 1000); + let m_hz = if let Some(m_hz) = mode.refresh_rate_millihertz() { + format!(" @ {}.{} Hz", m_hz / 1000, m_hz % 1000) + } else { + String::new() + }; + info!(" {width}x{height}x{bits}{m_hz}"); } } } diff --git a/src/changelog/unreleased.md b/src/changelog/unreleased.md index 98ab2dc7..b90ec4e5 100644 --- a/src/changelog/unreleased.md +++ b/src/changelog/unreleased.md @@ -95,6 +95,7 @@ changelog entry. accelerated, if the browser supports it. - `(Active)EventLoop::create_custom_cursor()` now returns a `Result`. - Changed how `ModifiersState` is serialized by Serde. +- `VideoModeHandle::refresh_rate_millihertz()` now returns an `Option`. ### Removed @@ -118,6 +119,8 @@ changelog entry. - Remove `DeviceEvent::Added` and `DeviceEvent::Removed`. - Remove `DeviceEvent::Motion` and `WindowEvent::AxisMotion`. - Remove `Touch::id` in favor of `Touch::finger_id`. +- Remove `MonitorHandle::size()` and `refresh_rate_millihertz()` in favor of + `MonitorHandle::current_video_mode()`. ### Fixed diff --git a/src/monitor.rs b/src/monitor.rs index d49742e3..df0b47dd 100644 --- a/src/monitor.rs +++ b/src/monitor.rs @@ -64,12 +64,8 @@ impl VideoModeHandle { } /// Returns the refresh rate of this video mode in mHz. - /// - /// ## Platform-specific - /// - /// **Web:** Always returns `0`. #[inline] - pub fn refresh_rate_millihertz(&self) -> u32 { + pub fn refresh_rate_millihertz(&self) -> Option { self.video_mode.refresh_rate_millihertz() } @@ -85,10 +81,10 @@ impl std::fmt::Display for VideoModeHandle { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, - "{}x{} @ {} mHz ({} bpp)", + "{}x{} {}({} bpp)", self.size().width, self.size().height, - self.refresh_rate_millihertz(), + self.refresh_rate_millihertz().map(|rate| format!("@ {rate} mHz ")).unwrap_or_default(), self.bit_depth() ) } @@ -139,12 +135,6 @@ impl MonitorHandle { self.inner.name() } - /// Returns the monitor's resolution. - #[inline] - pub fn size(&self) -> PhysicalSize { - self.inner.size() - } - /// Returns the top-left corner position of the monitor relative to the larger full /// screen area. /// @@ -161,22 +151,6 @@ impl MonitorHandle { self.inner.position() } - /// The monitor refresh rate used by the system. - /// - /// Return `Some` if succeed, or `None` if failed, which usually happens when the monitor - /// the window is on is removed. - /// - /// When using exclusive fullscreen, the refresh rate of the [`VideoModeHandle`] that was - /// used to enter fullscreen should be used instead. - /// - /// ## Platform-specific - /// - /// **Web:** Always returns [`None`]. - #[inline] - pub fn refresh_rate_millihertz(&self) -> Option { - self.inner.refresh_rate_millihertz() - } - /// Returns the scale factor of the underlying monitor. To map logical pixels to physical /// pixels and vice versa, use [`Window::scale_factor`]. /// diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index 1594f7d7..4d4c4336 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -204,9 +204,7 @@ impl EventLoop { let old_scale_factor = monitor.scale_factor(); let scale_factor = monitor.scale_factor(); if (scale_factor - old_scale_factor).abs() < f64::EPSILON { - let new_inner_size = Arc::new(Mutex::new( - MonitorHandle::new(self.android_app.clone()).size(), - )); + let new_inner_size = Arc::new(Mutex::new(screen_size(&self.android_app))); let window_id = window::WindowId(WindowId); let event = event::WindowEvent::ScaleFactorChanged { inner_size_writer: InnerSizeWriter::new(Arc::downgrade( @@ -789,7 +787,7 @@ impl Window { } pub fn outer_size(&self) -> PhysicalSize { - MonitorHandle::new(self.app.clone()).size() + screen_size(&self.app) } pub fn set_min_inner_size(&self, _: Option) {} @@ -982,14 +980,6 @@ impl MonitorHandle { Some("Android Device".to_owned()) } - pub fn size(&self) -> PhysicalSize { - if let Some(native_window) = self.app.native_window() { - PhysicalSize::new(native_window.width() as _, native_window.height() as _) - } else { - PhysicalSize::new(0, 0) - } - } - pub fn position(&self) -> PhysicalPosition { (0, 0).into() } @@ -998,19 +988,11 @@ impl MonitorHandle { self.app.config().density().map(|dpi| dpi as f64 / 160.0).unwrap_or(1.0) } - pub fn refresh_rate_millihertz(&self) -> Option { - // FIXME no way to get real refresh rate for now. - None - } - pub fn current_video_mode(&self) -> Option { - let size = self.size().into(); - // FIXME this is not the real refresh rate - // (it is guaranteed to support 32 bit color though) Some(VideoModeHandle { - size, + size: screen_size(&self.app), + // FIXME: it is guaranteed to support 32 bit color though bit_depth: 32, - refresh_rate_millihertz: 60000, monitor: self.clone(), }) } @@ -1022,26 +1004,33 @@ impl MonitorHandle { #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct VideoModeHandle { - size: (u32, u32), + size: PhysicalSize, bit_depth: u16, - refresh_rate_millihertz: u32, monitor: MonitorHandle, } impl VideoModeHandle { pub fn size(&self) -> PhysicalSize { - self.size.into() + self.size } pub fn bit_depth(&self) -> u16 { self.bit_depth } - pub fn refresh_rate_millihertz(&self) -> u32 { - self.refresh_rate_millihertz + pub fn refresh_rate_millihertz(&self) -> Option { + None } pub fn monitor(&self) -> MonitorHandle { self.monitor.clone() } } + +fn screen_size(app: &AndroidApp) -> PhysicalSize { + if let Some(native_window) = app.native_window() { + PhysicalSize::new(native_window.width() as _, native_window.height() as _) + } else { + PhysicalSize::new(0, 0) + } +} diff --git a/src/platform_impl/apple/appkit/monitor.rs b/src/platform_impl/apple/appkit/monitor.rs index 6b793f76..d6ca7a41 100644 --- a/src/platform_impl/apple/appkit/monitor.rs +++ b/src/platform_impl/apple/appkit/monitor.rs @@ -21,7 +21,7 @@ use crate::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize}; pub struct VideoModeHandle { size: PhysicalSize, bit_depth: u16, - refresh_rate_millihertz: u32, + refresh_rate_millihertz: Option, pub(crate) monitor: MonitorHandle, pub(crate) native_mode: NativeDisplayMode, } @@ -80,7 +80,11 @@ impl Clone for NativeDisplayMode { } impl VideoModeHandle { - fn new(monitor: MonitorHandle, mode: NativeDisplayMode, refresh_rate_millihertz: u32) -> Self { + fn new( + monitor: MonitorHandle, + mode: NativeDisplayMode, + refresh_rate_millihertz: Option, + ) -> Self { unsafe { let pixel_encoding = CFString::wrap_under_create_rule(ffi::CGDisplayModeCopyPixelEncoding(mode.0)) @@ -116,7 +120,7 @@ impl VideoModeHandle { self.bit_depth } - pub fn refresh_rate_millihertz(&self) -> u32 { + pub fn refresh_rate_millihertz(&self) -> Option { self.refresh_rate_millihertz } @@ -186,7 +190,6 @@ impl fmt::Debug for MonitorHandle { f.debug_struct("MonitorHandle") .field("name", &self.name()) .field("native_identifier", &self.native_identifier()) - .field("size", &self.size()) .field("position", &self.position()) .field("scale_factor", &self.scale_factor()) .field("refresh_rate_millihertz", &self.refresh_rate_millihertz()) @@ -212,14 +215,6 @@ impl MonitorHandle { self.0 } - pub fn size(&self) -> PhysicalSize { - let MonitorHandle(display_id) = *self; - let display = CGDisplay::new(display_id); - let height = display.pixels_high(); - let width = display.pixels_wide(); - PhysicalSize::from_logical::<_, f64>((width as f64, height as f64), self.scale_factor()) - } - #[inline] pub fn position(&self) -> PhysicalPosition { // This is already in screen coordinates. If we were using `NSScreen`, @@ -239,7 +234,7 @@ impl MonitorHandle { }) } - pub fn refresh_rate_millihertz(&self) -> Option { + fn refresh_rate_millihertz(&self) -> Option { let current_display_mode = NativeDisplayMode(unsafe { CGDisplayCopyDisplayMode(self.0) } as _); refresh_rate_millihertz(self.0, ¤t_display_mode) @@ -247,12 +242,12 @@ impl MonitorHandle { pub fn current_video_mode(&self) -> Option { let mode = NativeDisplayMode(unsafe { CGDisplayCopyDisplayMode(self.0) } as _); - let refresh_rate_millihertz = refresh_rate_millihertz(self.0, &mode).unwrap_or(0); + let refresh_rate_millihertz = refresh_rate_millihertz(self.0, &mode); Some(VideoModeHandle::new(self.clone(), mode, refresh_rate_millihertz)) } pub fn video_modes(&self) -> impl Iterator { - let refresh_rate_millihertz = self.refresh_rate_millihertz().unwrap_or(0); + let refresh_rate_millihertz = self.refresh_rate_millihertz(); let monitor = self.clone(); unsafe { @@ -277,7 +272,7 @@ impl MonitorHandle { // CGDisplayModeGetRefreshRate returns 0.0 for any display that // isn't a CRT let refresh_rate_millihertz = if cg_refresh_rate_hertz > 0 { - (cg_refresh_rate_hertz * 1000) as u32 + Some((cg_refresh_rate_hertz * 1000) as u32) } else { refresh_rate_millihertz }; diff --git a/src/platform_impl/apple/uikit/monitor.rs b/src/platform_impl/apple/uikit/monitor.rs index 2975afc7..4485e251 100644 --- a/src/platform_impl/apple/uikit/monitor.rs +++ b/src/platform_impl/apple/uikit/monitor.rs @@ -75,8 +75,8 @@ impl VideoModeHandle { self.bit_depth } - pub fn refresh_rate_millihertz(&self) -> u32 { - self.refresh_rate_millihertz + pub fn refresh_rate_millihertz(&self) -> Option { + Some(self.refresh_rate_millihertz) } pub fn monitor(&self) -> MonitorHandle { @@ -131,10 +131,8 @@ impl fmt::Debug for MonitorHandle { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("MonitorHandle") .field("name", &self.name()) - .field("size", &self.size()) .field("position", &self.position()) .field("scale_factor", &self.scale_factor()) - .field("refresh_rate_millihertz", &self.refresh_rate_millihertz()) .finish_non_exhaustive() } } @@ -164,11 +162,6 @@ impl MonitorHandle { }) } - pub fn size(&self) -> PhysicalSize { - let bounds = self.ui_screen.get_on_main(|ui_screen| ui_screen.nativeBounds()); - PhysicalSize::new(bounds.size.width as u32, bounds.size.height as u32) - } - pub fn position(&self) -> PhysicalPosition { let bounds = self.ui_screen.get_on_main(|ui_screen| ui_screen.nativeBounds()); (bounds.origin.x as f64, bounds.origin.y as f64).into() @@ -178,10 +171,6 @@ impl MonitorHandle { self.ui_screen.get_on_main(|ui_screen| ui_screen.nativeScale()) as f64 } - pub fn refresh_rate_millihertz(&self) -> Option { - Some(self.ui_screen.get_on_main(|ui_screen| refresh_rate_millihertz(ui_screen))) - } - pub fn current_video_mode(&self) -> Option { Some(run_on_main(|mtm| { VideoModeHandle::new( diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index 69edafda..039467dd 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -241,21 +241,11 @@ impl MonitorHandle { x11_or_wayland!(match self; MonitorHandle(m) => m.native_identifier()) } - #[inline] - pub fn size(&self) -> PhysicalSize { - x11_or_wayland!(match self; MonitorHandle(m) => m.size()) - } - #[inline] pub fn position(&self) -> PhysicalPosition { x11_or_wayland!(match self; MonitorHandle(m) => m.position()) } - #[inline] - pub fn refresh_rate_millihertz(&self) -> Option { - x11_or_wayland!(match self; MonitorHandle(m) => m.refresh_rate_millihertz()) - } - #[inline] pub fn scale_factor(&self) -> f64 { x11_or_wayland!(match self; MonitorHandle(m) => m.scale_factor() as _) @@ -292,7 +282,7 @@ impl VideoModeHandle { } #[inline] - pub fn refresh_rate_millihertz(&self) -> u32 { + pub fn refresh_rate_millihertz(&self) -> Option { x11_or_wayland!(match self; VideoModeHandle(m) => m.refresh_rate_millihertz()) } diff --git a/src/platform_impl/linux/wayland/output.rs b/src/platform_impl/linux/wayland/output.rs index 8c793be6..3f7d5da7 100644 --- a/src/platform_impl/linux/wayland/output.rs +++ b/src/platform_impl/linux/wayland/output.rs @@ -28,20 +28,6 @@ impl MonitorHandle { output_data.with_output_info(|info| info.id) } - #[inline] - pub fn size(&self) -> PhysicalSize { - let output_data = self.proxy.data::().unwrap(); - let dimensions = output_data.with_output_info(|info| { - info.modes.iter().find_map(|mode| mode.current.then_some(mode.dimensions)) - }); - - match dimensions { - Some((width, height)) => (width as u32, height as u32), - _ => (0, 0), - } - .into() - } - #[inline] pub fn position(&self) -> PhysicalPosition { let output_data = self.proxy.data::().unwrap(); @@ -59,14 +45,6 @@ impl MonitorHandle { }) } - #[inline] - pub fn refresh_rate_millihertz(&self) -> Option { - let output_data = self.proxy.data::().unwrap(); - output_data.with_output_info(|info| { - info.modes.iter().find_map(|mode| mode.current.then_some(mode.refresh_rate as u32)) - }) - } - #[inline] pub fn scale_factor(&self) -> i32 { let output_data = self.proxy.data::().unwrap(); @@ -153,8 +131,8 @@ impl VideoModeHandle { } #[inline] - pub fn refresh_rate_millihertz(&self) -> u32 { - self.refresh_rate_millihertz + pub fn refresh_rate_millihertz(&self) -> Option { + Some(self.refresh_rate_millihertz) } pub fn monitor(&self) -> MonitorHandle { diff --git a/src/platform_impl/linux/x11/monitor.rs b/src/platform_impl/linux/x11/monitor.rs index 0dd4abfc..1347b8e1 100644 --- a/src/platform_impl/linux/x11/monitor.rs +++ b/src/platform_impl/linux/x11/monitor.rs @@ -21,7 +21,7 @@ pub struct VideoModeHandle { pub(crate) current: bool, pub(crate) size: (u32, u32), pub(crate) bit_depth: u16, - pub(crate) refresh_rate_millihertz: u32, + pub(crate) refresh_rate_millihertz: Option, pub(crate) native_mode: randr::Mode, pub(crate) monitor: Option, } @@ -38,7 +38,7 @@ impl VideoModeHandle { } #[inline] - pub fn refresh_rate_millihertz(&self) -> u32 { + pub fn refresh_rate_millihertz(&self) -> Option { self.refresh_rate_millihertz } @@ -54,8 +54,6 @@ pub struct MonitorHandle { pub(crate) id: randr::Crtc, /// The name of the monitor pub(crate) name: String, - /// The size of the monitor - dimensions: (u32, u32), /// The position of the monitor in the X screen position: (i32, i32), /// If the monitor is the primary one @@ -118,16 +116,7 @@ impl MonitorHandle { let rect = util::AaRect::new(position, dimensions); - Some(MonitorHandle { - id, - name, - scale_factor, - dimensions, - position, - primary, - rect, - video_modes, - }) + Some(MonitorHandle { id, name, scale_factor, position, primary, rect, video_modes }) } pub fn dummy() -> Self { @@ -135,7 +124,6 @@ impl MonitorHandle { id: 0, name: "".into(), scale_factor: 1.0, - dimensions: (1, 1), position: (0, 0), primary: true, rect: util::AaRect::new((0, 0), (1, 1)), @@ -157,20 +145,10 @@ impl MonitorHandle { self.id as _ } - pub fn size(&self) -> PhysicalSize { - self.dimensions.into() - } - pub fn position(&self) -> PhysicalPosition { self.position.into() } - pub fn refresh_rate_millihertz(&self) -> Option { - self.video_modes - .iter() - .find_map(|mode| mode.current.then_some(mode.refresh_rate_millihertz)) - } - #[inline] pub fn scale_factor(&self) -> f64 { self.scale_factor diff --git a/src/platform_impl/linux/x11/util/randr.rs b/src/platform_impl/linux/x11/util/randr.rs index 4f27801b..429e69ac 100644 --- a/src/platform_impl/linux/x11/util/randr.rs +++ b/src/platform_impl/linux/x11/util/randr.rs @@ -85,8 +85,7 @@ impl XConnection { VideoModeHandle { current: mode.id == current_mode, size: (mode.width.into(), mode.height.into()), - refresh_rate_millihertz: monitor::mode_refresh_rate_millihertz(mode) - .unwrap_or(0), + refresh_rate_millihertz: monitor::mode_refresh_rate_millihertz(mode), bit_depth: bit_depth as u16, native_mode: mode.id, // This is populated in `MonitorHandle::video_modes` as the diff --git a/src/platform_impl/orbital/mod.rs b/src/platform_impl/orbital/mod.rs index 4e0979cc..076db505 100644 --- a/src/platform_impl/orbital/mod.rs +++ b/src/platform_impl/orbital/mod.rs @@ -200,10 +200,6 @@ impl MonitorHandle { Some("Redox Device".to_owned()) } - pub fn size(&self) -> PhysicalSize { - PhysicalSize::new(0, 0) // TODO - } - pub fn position(&self) -> PhysicalPosition { (0, 0).into() } @@ -212,19 +208,11 @@ impl MonitorHandle { 1.0 // TODO } - pub fn refresh_rate_millihertz(&self) -> Option { - // FIXME no way to get real refresh rate for now. - None - } - pub fn current_video_mode(&self) -> Option { - let size = self.size().into(); - // FIXME this is not the real refresh rate // (it is guaranteed to support 32 bit color though) Some(VideoModeHandle { - size, + size: PhysicalSize::default(), // TODO bit_depth: 32, - refresh_rate_millihertz: 60000, monitor: self.clone(), }) } @@ -236,23 +224,23 @@ impl MonitorHandle { #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct VideoModeHandle { - size: (u32, u32), + size: PhysicalSize, bit_depth: u16, - refresh_rate_millihertz: u32, monitor: MonitorHandle, } impl VideoModeHandle { pub fn size(&self) -> PhysicalSize { - self.size.into() + self.size } pub fn bit_depth(&self) -> u16 { self.bit_depth } - pub fn refresh_rate_millihertz(&self) -> u32 { - self.refresh_rate_millihertz + pub fn refresh_rate_millihertz(&self) -> Option { + // TODO + None } pub fn monitor(&self) -> MonitorHandle { diff --git a/src/platform_impl/web/monitor.rs b/src/platform_impl/web/monitor.rs index 678056d7..700a4484 100644 --- a/src/platform_impl/web/monitor.rs +++ b/src/platform_impl/web/monitor.rs @@ -71,24 +71,6 @@ impl MonitorHandle { }) } - pub fn refresh_rate_millihertz(&self) -> Option { - None - } - - pub fn size(&self) -> PhysicalSize { - self.inner.queue(|inner| { - let width = inner.screen.width().unwrap(); - let height = inner.screen.height().unwrap(); - - if let Some(Engine::Chromium) = inner.engine { - PhysicalSize::new(width, height).cast() - } else { - LogicalSize::new(width, height) - .to_physical(super::web_sys::scale_factor(&inner.window)) - } - }) - } - pub fn current_video_mode(&self) -> Option { Some(VideoModeHandle(self.clone())) } @@ -291,15 +273,25 @@ pub struct VideoModeHandle(pub(super) MonitorHandle); impl VideoModeHandle { pub fn size(&self) -> PhysicalSize { - self.0.size() + self.0.inner.queue(|inner| { + let width = inner.screen.width().unwrap(); + let height = inner.screen.height().unwrap(); + + if let Some(Engine::Chromium) = inner.engine { + PhysicalSize::new(width, height).cast() + } else { + LogicalSize::new(width, height) + .to_physical(super::web_sys::scale_factor(&inner.window)) + } + }) } pub fn bit_depth(&self) -> u16 { self.0.inner.queue(|inner| inner.screen.color_depth().unwrap()).try_into().unwrap() } - pub fn refresh_rate_millihertz(&self) -> u32 { - 0 + pub fn refresh_rate_millihertz(&self) -> Option { + None } pub fn monitor(&self) -> MonitorHandle { diff --git a/src/platform_impl/windows/monitor.rs b/src/platform_impl/windows/monitor.rs index 4f658167..e179e85e 100644 --- a/src/platform_impl/windows/monitor.rs +++ b/src/platform_impl/windows/monitor.rs @@ -81,8 +81,8 @@ impl VideoModeHandle { self.bit_depth } - pub fn refresh_rate_millihertz(&self) -> u32 { - self.refresh_rate_millihertz + pub fn refresh_rate_millihertz(&self) -> Option { + Some(self.refresh_rate_millihertz) } pub fn monitor(&self) -> MonitorHandle { @@ -180,8 +180,7 @@ impl MonitorHandle { self.0 } - #[inline] - pub fn size(&self) -> PhysicalSize { + pub(crate) fn size(&self) -> PhysicalSize { let rc_monitor = get_monitor_info(self.0).unwrap().monitorInfo.rcMonitor; PhysicalSize { width: (rc_monitor.right - rc_monitor.left) as u32, @@ -189,23 +188,6 @@ impl MonitorHandle { } } - #[inline] - pub fn refresh_rate_millihertz(&self) -> Option { - let monitor_info = get_monitor_info(self.0).ok()?; - let device_name = monitor_info.szDevice.as_ptr(); - unsafe { - let mut mode: DEVMODEW = mem::zeroed(); - mode.dmSize = mem::size_of_val(&mode) as u16; - if EnumDisplaySettingsExW(device_name, ENUM_CURRENT_SETTINGS, &mut mode, 0) - == false.into() - { - None - } else { - Some(mode.dmDisplayFrequency * 1000) - } - } - } - #[inline] pub fn position(&self) -> PhysicalPosition { get_monitor_info(self.0)