Skip to content

Commit 04482d5

Browse files
authored
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.
1 parent 3e50911 commit 04482d5

File tree

4 files changed

+18
-6
lines changed

4 files changed

+18
-6
lines changed

src/changelog/unreleased.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,3 +248,4 @@ changelog entry.
248248
- On macOS, fixed the scancode conversion for audio volume keys.
249249
- On macOS, fixed the scancode conversion for `IntlBackslash`.
250250
- On macOS, fixed redundant `SurfaceResized` event at window creation.
251+
- On macOS, don't panic on monitors with unknown bit-depths.

src/platform_impl/apple/appkit/ffi.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use objc2_core_graphics::CGDirectDisplayID;
1111

1212
pub const IO16BitDirectPixels: &str = "-RRRRRGGGGGBBBBB";
1313
pub const IO32BitDirectPixels: &str = "--------RRRRRRRRGGGGGGGGBBBBBBBB";
14-
1514
pub const kIO30BitDirectPixels: &str = "--RRRRRRRRRRGGGGGGGGGGBBBBBBBBBB";
15+
pub const kIO64BitDirectPixels: &str = "-16R16G16B16";
1616

1717
// `CGDisplayCreateUUIDFromDisplayID` comes from the `ColorSync` framework.
1818
// However, that framework was only introduced "publicly" in macOS 10.13.

src/platform_impl/apple/appkit/monitor.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,25 +66,29 @@ impl VideoModeHandle {
6666
refresh_rate_millihertz: Option<NonZeroU32>,
6767
) -> Self {
6868
unsafe {
69+
// The bit-depth is basically always 32 since macOS 10.12.
6970
#[allow(deprecated)]
7071
let pixel_encoding =
7172
CGDisplayMode::pixel_encoding(Some(&native_mode.0)).unwrap().to_string();
7273
let bit_depth = if pixel_encoding.eq_ignore_ascii_case(ffi::IO32BitDirectPixels) {
73-
32
74+
NonZeroU16::new(32)
7475
} else if pixel_encoding.eq_ignore_ascii_case(ffi::IO16BitDirectPixels) {
75-
16
76+
NonZeroU16::new(16)
7677
} else if pixel_encoding.eq_ignore_ascii_case(ffi::kIO30BitDirectPixels) {
77-
30
78+
NonZeroU16::new(30)
79+
} else if pixel_encoding.eq_ignore_ascii_case(ffi::kIO64BitDirectPixels) {
80+
NonZeroU16::new(64)
7881
} else {
79-
unimplemented!()
82+
warn!(?pixel_encoding, "unknown bit depth");
83+
None
8084
};
8185

8286
let mode = VideoMode::new(
8387
PhysicalSize::new(
8488
CGDisplayMode::pixel_width(Some(&native_mode.0)) as u32,
8589
CGDisplayMode::pixel_height(Some(&native_mode.0)) as u32,
8690
),
87-
NonZeroU16::new(bit_depth),
91+
bit_depth,
8892
refresh_rate_millihertz,
8993
);
9094

winit-core/src/monitor.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,13 @@ impl VideoMode {
151151
/// Returns the bit depth of this video mode, as in how many bits you have
152152
/// available per color. This is generally 24 bits or 32 bits on modern
153153
/// systems, depending on whether the alpha channel is counted or not.
154+
///
155+
/// # Platform-specific
156+
///
157+
/// - **macOS**: Video modes do not control the bit depth of the monitor, so this often defaults
158+
/// to 32.
159+
/// - **iOS**: Always returns `None`.
160+
/// - **Wayland**: Always returns `None`.
154161
pub fn bit_depth(&self) -> Option<NonZeroU16> {
155162
self.bit_depth
156163
}

0 commit comments

Comments
 (0)