mirror of
https://github.com/rust-windowing/winit.git
synced 2026-08-31 05:40:04 -04:00
macOS: Fix monitors connected via certain Thunderbolt hubs
Instead of panicking, raise a warning and return `None` or similar. Co-Authored-By: RJ <rj@metabrew.com>
This commit is contained in:
committed by
Kirill Chibisov
parent
5f1e9f6cc1
commit
80bddda641
@@ -65,3 +65,4 @@ changelog entry.
|
|||||||
- On macOS, fixed `run_app_on_demand` returning without closing open windows.
|
- On macOS, fixed `run_app_on_demand` returning without closing open windows.
|
||||||
- On macOS, fixed `VideoMode::refresh_rate_millihertz` for fractional refresh rates.
|
- On macOS, fixed `VideoMode::refresh_rate_millihertz` for fractional refresh rates.
|
||||||
- On macOS, store monitor handle to avoid panics after going in/out of sleep.
|
- On macOS, store monitor handle to avoid panics after going in/out of sleep.
|
||||||
|
- On macOS, allow certain invalid monitor handles and return `None` instead of panicking.
|
||||||
|
|||||||
@@ -291,17 +291,24 @@ impl MonitorHandle {
|
|||||||
unsafe {
|
unsafe {
|
||||||
let modes = {
|
let modes = {
|
||||||
let array = ffi::CGDisplayCopyAllDisplayModes(self.display_id(), std::ptr::null());
|
let array = ffi::CGDisplayCopyAllDisplayModes(self.display_id(), std::ptr::null());
|
||||||
assert!(!array.is_null(), "failed to get list of display modes");
|
if array.is_null() {
|
||||||
let array_count = CFArrayGetCount(array);
|
// Occasionally, certain CalDigit Thunderbolt Hubs report a spurious monitor
|
||||||
let modes: Vec<_> = (0..array_count)
|
// during sleep/wake/cycling monitors. It tends to have null
|
||||||
.map(move |i| {
|
// or 1 video mode only. See <https://github.com/bevyengine/bevy/issues/17827>.
|
||||||
let mode = CFArrayGetValueAtIndex(array, i) as *mut _;
|
warn!(monitor = ?self, "failed to get a list of display modes");
|
||||||
ffi::CGDisplayModeRetain(mode);
|
Vec::new()
|
||||||
mode
|
} else {
|
||||||
})
|
let array_count = CFArrayGetCount(array);
|
||||||
.collect();
|
let modes: Vec<_> = (0..array_count)
|
||||||
CFRelease(array as *const _);
|
.map(move |i| {
|
||||||
modes
|
let mode = CFArrayGetValueAtIndex(array, i) as *mut _;
|
||||||
|
ffi::CGDisplayModeRetain(mode);
|
||||||
|
mode
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
CFRelease(array as *const _);
|
||||||
|
modes
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
modes.into_iter().map(move |mode| {
|
modes.into_iter().map(move |mode| {
|
||||||
@@ -346,9 +353,14 @@ impl MonitorHandle {
|
|||||||
let uuid = self.uuid();
|
let uuid = self.uuid();
|
||||||
NSScreen::screens(mtm).into_iter().find(|screen| {
|
NSScreen::screens(mtm).into_iter().find(|screen| {
|
||||||
let other_native_id = get_display_id(screen);
|
let other_native_id = get_display_id(screen);
|
||||||
// Display ID just fetched from live NSScreen, should be fine to unwrap.
|
if let Some(other) = MonitorHandle::new(other_native_id) {
|
||||||
let other = MonitorHandle::new(other_native_id).expect("invalid display ID");
|
uuid == other.uuid()
|
||||||
uuid == other.uuid()
|
} else {
|
||||||
|
// Display ID was just fetched from live NSScreen, but can still result in `None`
|
||||||
|
// with certain Thunderbolt docked monitors.
|
||||||
|
warn!(other_native_id, "comparing against screen with invalid display ID");
|
||||||
|
false
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1592,8 +1592,14 @@ impl WindowDelegate {
|
|||||||
// Allow directly accessing the current monitor internally without unwrapping.
|
// Allow directly accessing the current monitor internally without unwrapping.
|
||||||
pub(crate) fn current_monitor_inner(&self) -> Option<MonitorHandle> {
|
pub(crate) fn current_monitor_inner(&self) -> Option<MonitorHandle> {
|
||||||
let display_id = get_display_id(&*self.window().screen()?);
|
let display_id = get_display_id(&*self.window().screen()?);
|
||||||
// Display ID just fetched from live NSScreen, should be fine to unwrap.
|
if let Some(monitor) = MonitorHandle::new(display_id) {
|
||||||
Some(MonitorHandle::new(display_id).expect("invalid display ID"))
|
Some(monitor)
|
||||||
|
} else {
|
||||||
|
// NOTE: Display ID was just fetched from live NSScreen, but can still result in `None`
|
||||||
|
// with certain Thunderbolt docked monitors.
|
||||||
|
warn!(display_id, "got screen with invalid display ID");
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|||||||
Reference in New Issue
Block a user