Don't panic when getting refresh rate failed (#2533)

This fixes a crash on macOS when trying to get the monitor
refresh rate from the disabled monitor.

Co-authored-by: Jet Spark <lixiaopeng.jetspark@bytedance.com>
Co-authored-by: Mads Marquart <mads@marquart.dk>
This commit is contained in:
Xiaopeng Li 2022-11-29 18:28:46 +08:00 committed by GitHub
parent 94688a62f0
commit 32784af3c4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 13 additions and 7 deletions

View file

@ -8,6 +8,7 @@ And please only add new entries to the top of this list, right below the `# Unre
# Unreleased
- On macOS, fix panic when getting current monitor without any monitor attached.
- On Windows and MacOS, add API to enable/disable window buttons (close, minimize, ...etc).
- On Windows, macOS, X11 and Wayland, add `Window::set_theme`.
- **Breaking:** Remove `WindowExtWayland::wayland_set_csd_theme` and `WindowBuilderExtX11::with_gtk_theme_variant`.
@ -41,7 +42,6 @@ And please only add new entries to the top of this list, right below the `# Unre
- **Breaking:** Removed `WindowBuilderExtWindows::with_theme` and `WindowBuilderExtWayland::with_wayland_csd_theme` in favour of `WindowBuilder::with_theme`.
- **Breaking:** Removed `WindowExtWindows::theme` in favour of `Window::theme`.
- Enabled `doc_auto_cfg` when generating docs on docs.rs for feature labels.
- On macOS, fix panic when getting current monitor without any monitor attached.
- **Breaking:** On Android, switched to using [`android-activity`](https://github.com/rib/android-activity) crate as a glue layer instead of [`ndk-glue](https://github.com/rust-windowing/android-ndk-rs/tree/master/ndk-glue). See [README.md#Android](https://github.com/rust-windowing/winit#Android) for more details. ([#2444](https://github.com/rust-windowing/winit/pull/2444))
# 0.27.5

View file

@ -143,6 +143,9 @@ impl MonitorHandle {
/// 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 [`VideoMode`] that was used to
/// enter fullscreen should be used instead.
#[inline]

View file

@ -215,15 +215,18 @@ impl MonitorHandle {
pub fn refresh_rate_millihertz(&self) -> Option<u32> {
unsafe {
let mut display_link = std::ptr::null_mut();
assert_eq!(
ffi::CVDisplayLinkCreateWithCGDisplay(self.0, &mut display_link),
ffi::kCVReturnSuccess
);
if ffi::CVDisplayLinkCreateWithCGDisplay(self.0, &mut display_link)
!= ffi::kCVReturnSuccess
{
return None;
}
let time = ffi::CVDisplayLinkGetNominalOutputVideoRefreshPeriod(display_link);
ffi::CVDisplayLinkRelease(display_link);
// This value is indefinite if an invalid display link was specified
assert!(time.flags & ffi::kCVTimeIsIndefinite == 0);
if time.flags & ffi::kCVTimeIsIndefinite != 0 {
return None;
}
Some((time.time_scale as i64 / time.time_value * 1000) as u32)
}

View file

@ -192,7 +192,7 @@ impl MonitorHandle {
#[inline]
pub fn refresh_rate_millihertz(&self) -> Option<u32> {
let monitor_info = get_monitor_info(self.0).unwrap();
let monitor_info = get_monitor_info(self.0).ok()?;
let device_name = monitor_info.szDevice.as_ptr();
unsafe {
let mut mode: DEVMODEW = mem::zeroed();