fix: Allow unknown bit-depth on macOS (#4190)

It is unclear what values CGDisplayModeCopyPixelEncoding is allowed to
return, so let's make sure to handle unknown cases.
This commit is contained in:
Mads Marquart 2025-05-23 16:07:09 +02:00 committed by GitHub
parent 3e50911adb
commit 04482d5a2e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 18 additions and 6 deletions

View file

@ -248,3 +248,4 @@ changelog entry.
- On macOS, fixed the scancode conversion for audio volume keys.
- On macOS, fixed the scancode conversion for `IntlBackslash`.
- On macOS, fixed redundant `SurfaceResized` event at window creation.
- On macOS, don't panic on monitors with unknown bit-depths.

View file

@ -11,8 +11,8 @@ use objc2_core_graphics::CGDirectDisplayID;
pub const IO16BitDirectPixels: &str = "-RRRRRGGGGGBBBBB";
pub const IO32BitDirectPixels: &str = "--------RRRRRRRRGGGGGGGGBBBBBBBB";
pub const kIO30BitDirectPixels: &str = "--RRRRRRRRRRGGGGGGGGGGBBBBBBBBBB";
pub const kIO64BitDirectPixels: &str = "-16R16G16B16";
// `CGDisplayCreateUUIDFromDisplayID` comes from the `ColorSync` framework.
// However, that framework was only introduced "publicly" in macOS 10.13.

View file

@ -66,17 +66,21 @@ impl VideoModeHandle {
refresh_rate_millihertz: Option<NonZeroU32>,
) -> Self {
unsafe {
// The bit-depth is basically always 32 since macOS 10.12.
#[allow(deprecated)]
let pixel_encoding =
CGDisplayMode::pixel_encoding(Some(&native_mode.0)).unwrap().to_string();
let bit_depth = if pixel_encoding.eq_ignore_ascii_case(ffi::IO32BitDirectPixels) {
32
NonZeroU16::new(32)
} else if pixel_encoding.eq_ignore_ascii_case(ffi::IO16BitDirectPixels) {
16
NonZeroU16::new(16)
} else if pixel_encoding.eq_ignore_ascii_case(ffi::kIO30BitDirectPixels) {
30
NonZeroU16::new(30)
} else if pixel_encoding.eq_ignore_ascii_case(ffi::kIO64BitDirectPixels) {
NonZeroU16::new(64)
} else {
unimplemented!()
warn!(?pixel_encoding, "unknown bit depth");
None
};
let mode = VideoMode::new(
@ -84,7 +88,7 @@ impl VideoModeHandle {
CGDisplayMode::pixel_width(Some(&native_mode.0)) as u32,
CGDisplayMode::pixel_height(Some(&native_mode.0)) as u32,
),
NonZeroU16::new(bit_depth),
bit_depth,
refresh_rate_millihertz,
);

View file

@ -151,6 +151,13 @@ impl VideoMode {
/// Returns the bit depth of this video mode, as in how many bits you have
/// available per color. This is generally 24 bits or 32 bits on modern
/// systems, depending on whether the alpha channel is counted or not.
///
/// # Platform-specific
///
/// - **macOS**: Video modes do not control the bit depth of the monitor, so this often defaults
/// to 32.
/// - **iOS**: Always returns `None`.
/// - **Wayland**: Always returns `None`.
pub fn bit_depth(&self) -> Option<NonZeroU16> {
self.bit_depth
}