Skip to content

Commit 87d8a93

Browse files
committed
Use wrapper type for CFUUID
This no longer exposes `CGDisplayCreateUUIDFromDisplayID` and instead offers a new `CfUuid` type that can be created from a display ID and also cleans itself up on drop. Closes #4031
1 parent 171d53c commit 87d8a93

File tree

2 files changed

+31
-16
lines changed

2 files changed

+31
-16
lines changed

src/platform_impl/apple/appkit/ffi.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,25 @@ pub type CGDisplayModeRef = *mut c_void;
6767
// https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/OSX_Technology_Overview/SystemFrameworks/SystemFrameworks.html#//apple_ref/doc/uid/TP40001067-CH210-BBCFFIEG
6868
#[link(name = "ApplicationServices", kind = "framework")]
6969
extern "C" {
70-
pub fn CGDisplayCreateUUIDFromDisplayID(display: CGDirectDisplayID) -> CFUUIDRef;
70+
fn CGDisplayCreateUUIDFromDisplayID(display: CGDirectDisplayID) -> CFUUIDRef;
71+
}
72+
73+
/// Convenice wrapper around `CFUUIDRef` which releases on drop.
74+
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
75+
pub(crate) struct CfUuid(pub(crate) CFUUIDRef);
76+
77+
impl CfUuid {
78+
pub fn from_display_id(value: CGDirectDisplayID) -> Self {
79+
CfUuid(unsafe { CGDisplayCreateUUIDFromDisplayID(value) })
80+
}
81+
}
82+
83+
impl Drop for CfUuid {
84+
fn drop(&mut self) {
85+
unsafe {
86+
core_foundation::base::CFRelease(self.0 as *const _);
87+
}
88+
}
7189
}
7290

7391
#[link(name = "CoreGraphics", kind = "framework")]

src/platform_impl/apple/appkit/monitor.rs

+12-15
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,19 @@ impl VideoModeHandle {
133133
#[derive(Clone)]
134134
pub struct MonitorHandle(CGDirectDisplayID);
135135

136+
impl MonitorHandle {
137+
/// Internal comparisons of [`MonitorHandle`]s are done first requesting a UUID for the handle.
138+
fn uuid(&self) -> ffi::CfUuid {
139+
ffi::CfUuid::from_display_id(self.0)
140+
}
141+
}
142+
136143
// `CGDirectDisplayID` changes on video mode change, so we cannot rely on that
137144
// for comparisons, but we can use `CGDisplayCreateUUIDFromDisplayID` to get an
138145
// unique identifier that persists even across system reboots
139146
impl PartialEq for MonitorHandle {
140147
fn eq(&self, other: &Self) -> bool {
141-
unsafe {
142-
ffi::CGDisplayCreateUUIDFromDisplayID(self.0)
143-
== ffi::CGDisplayCreateUUIDFromDisplayID(other.0)
144-
}
148+
self.uuid() == other.uuid()
145149
}
146150
}
147151

@@ -155,18 +159,13 @@ impl PartialOrd for MonitorHandle {
155159

156160
impl Ord for MonitorHandle {
157161
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
158-
unsafe {
159-
ffi::CGDisplayCreateUUIDFromDisplayID(self.0)
160-
.cmp(&ffi::CGDisplayCreateUUIDFromDisplayID(other.0))
161-
}
162+
self.uuid().cmp(&other.uuid())
162163
}
163164
}
164165

165166
impl std::hash::Hash for MonitorHandle {
166167
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
167-
unsafe {
168-
ffi::CGDisplayCreateUUIDFromDisplayID(self.0).hash(state);
169-
}
168+
self.uuid().hash(state);
170169
}
171170
}
172171

@@ -287,12 +286,10 @@ impl MonitorHandle {
287286
}
288287

289288
pub(crate) fn ns_screen(&self, mtm: MainThreadMarker) -> Option<Retained<NSScreen>> {
290-
let uuid = unsafe { ffi::CGDisplayCreateUUIDFromDisplayID(self.0) };
289+
let uuid = self.uuid();
291290
NSScreen::screens(mtm).into_iter().find(|screen| {
292291
let other_native_id = get_display_id(screen);
293-
let other_uuid = unsafe {
294-
ffi::CGDisplayCreateUUIDFromDisplayID(other_native_id as CGDirectDisplayID)
295-
};
292+
let other_uuid = ffi::CfUuid::from_display_id(other_native_id);
296293
uuid == other_uuid
297294
})
298295
}

0 commit comments

Comments
 (0)