Skip to content

Commit

Permalink
MacOS: Use UUIDBytes for monitor comparisons etc.
Browse files Browse the repository at this point in the history
  • Loading branch information
killercup committed Dec 17, 2024
1 parent 71b0bc2 commit 4b5ee2b
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 23 deletions.
20 changes: 1 addition & 19 deletions src/platform_impl/apple/appkit/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,25 +67,7 @@ pub type CGDisplayModeRef = *mut c_void;
// https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/OSX_Technology_Overview/SystemFrameworks/SystemFrameworks.html#//apple_ref/doc/uid/TP40001067-CH210-BBCFFIEG
#[link(name = "ApplicationServices", kind = "framework")]
extern "C" {
fn CGDisplayCreateUUIDFromDisplayID(display: CGDirectDisplayID) -> CFUUIDRef;
}

/// Convenice wrapper around `CFUUIDRef` which releases on drop.
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
pub(crate) struct CfUuid(pub(crate) CFUUIDRef);

impl CfUuid {
pub fn from_display_id(value: CGDirectDisplayID) -> Self {
CfUuid(unsafe { CGDisplayCreateUUIDFromDisplayID(value) })
}
}

impl Drop for CfUuid {
fn drop(&mut self) {
unsafe {
core_foundation::base::CFRelease(self.0 as *const _);
}
}
pub fn CGDisplayCreateUUIDFromDisplayID(display: CGDirectDisplayID) -> CFUUIDRef;
}

#[link(name = "CoreGraphics", kind = "framework")]
Expand Down
33 changes: 29 additions & 4 deletions src/platform_impl/apple/appkit/monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::num::{NonZeroU16, NonZeroU32};
use core_foundation::array::{CFArrayGetCount, CFArrayGetValueAtIndex};
use core_foundation::base::{CFRelease, TCFType};
use core_foundation::string::CFString;
use core_foundation::uuid::{CFUUIDGetUUIDBytes, CFUUID};
use core_graphics::display::{
CGDirectDisplayID, CGDisplay, CGDisplayBounds, CGDisplayCopyDisplayMode,
};
Expand Down Expand Up @@ -133,10 +134,34 @@ impl VideoModeHandle {
#[derive(Clone)]
pub struct MonitorHandle(CGDirectDisplayID);

#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
struct MonitorUuid([u8; 16]);

impl MonitorHandle {
/// Internal comparisons of [`MonitorHandle`]s are done first requesting a UUID for the handle.
fn uuid(&self) -> ffi::CfUuid {
ffi::CfUuid::from_display_id(self.0)
fn uuid(&self) -> MonitorUuid {
let cf_uuid = unsafe {
CFUUID::wrap_under_create_rule(ffi::CGDisplayCreateUUIDFromDisplayID(self.0))
};
let uuid = unsafe { CFUUIDGetUUIDBytes(cf_uuid.as_concrete_TypeRef()) };
MonitorUuid([
uuid.byte0,
uuid.byte1,
uuid.byte2,
uuid.byte3,
uuid.byte4,
uuid.byte5,
uuid.byte6,
uuid.byte7,
uuid.byte8,
uuid.byte9,
uuid.byte10,
uuid.byte11,
uuid.byte12,
uuid.byte13,
uuid.byte14,
uuid.byte15,
])
}
}

Expand Down Expand Up @@ -289,8 +314,8 @@ impl MonitorHandle {
let uuid = self.uuid();
NSScreen::screens(mtm).into_iter().find(|screen| {
let other_native_id = get_display_id(screen);
let other_uuid = ffi::CfUuid::from_display_id(other_native_id);
uuid == other_uuid
let other = MonitorHandle::new(other_native_id);
uuid == other.uuid()
})
}
}
Expand Down

0 comments on commit 4b5ee2b

Please sign in to comment.