From 30971348747d25b5c6e1f15ffb22e7361444ac87 Mon Sep 17 00:00:00 2001 From: Raphael Amorim Date: Sat, 18 Jan 2025 23:06:47 -0300 Subject: [PATCH] Use wrapper type for CFUUID retired from (https://github.com/rust-windowing/winit/pull/4032) --- docs/docs/features/shell-integration.md | 14 +++++ rio-window/src/platform_impl/macos/monitor.rs | 55 +++++++++++++------ 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/docs/docs/features/shell-integration.md b/docs/docs/features/shell-integration.md index 966a8459a0..30733ee206 100644 --- a/docs/docs/features/shell-integration.md +++ b/docs/docs/features/shell-integration.md @@ -10,3 +10,17 @@ Rio supports integrating with the shell through the following means: - OSC 1337 Escape sequences to set user vars for tracking additional shell state. OSC is escape sequence jargon for Operating System Command. + +## Title integration + +Programs notify Rio of the current working directory and document by sending it commands. You may need to configure your shell or other programs to enable this behavior. + +The working directory and location of the current document may be set using the Operating System Command (OSC) escape sequence: + +``` +ESC ] Ps ; Pt BEL +``` + +The parameter Ps is either 6 (document) or 7 (working directory) and Pt is a “file:” URL. The URL should include a hostname to disambiguate local and remote paths, and characters must be percent-encoded as appropriate. + +When both the working directory and document are set only the document is displayed. diff --git a/rio-window/src/platform_impl/macos/monitor.rs b/rio-window/src/platform_impl/macos/monitor.rs index 0ed04f554e..36a015bab8 100644 --- a/rio-window/src/platform_impl/macos/monitor.rs +++ b/rio-window/src/platform_impl/macos/monitor.rs @@ -6,6 +6,7 @@ use std::fmt; 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, }; @@ -102,15 +103,42 @@ impl VideoModeHandle { #[derive(Clone)] pub struct MonitorHandle(CGDirectDisplayID); +type MonitorUuid = [u8; 16]; + +impl MonitorHandle { + /// Internal comparisons of [`MonitorHandle`]s are done first requesting a UUID for the handle. + 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::from([ + 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, + ]) + } +} + // `CGDirectDisplayID` changes on video mode change, so we cannot rely on that // for comparisons, but we can use `CGDisplayCreateUUIDFromDisplayID` to get an // unique identifier that persists even across system reboots impl PartialEq for MonitorHandle { fn eq(&self, other: &Self) -> bool { - unsafe { - ffi::CGDisplayCreateUUIDFromDisplayID(self.0) - == ffi::CGDisplayCreateUUIDFromDisplayID(other.0) - } + self.uuid() == other.uuid() } } @@ -124,18 +152,13 @@ impl PartialOrd for MonitorHandle { impl Ord for MonitorHandle { fn cmp(&self, other: &Self) -> std::cmp::Ordering { - unsafe { - ffi::CGDisplayCreateUUIDFromDisplayID(self.0) - .cmp(&ffi::CGDisplayCreateUUIDFromDisplayID(other.0)) - } + self.uuid().cmp(&other.uuid()) } } impl std::hash::Hash for MonitorHandle { fn hash(&self, state: &mut H) { - unsafe { - ffi::CGDisplayCreateUUIDFromDisplayID(self.0).hash(state); - } + self.uuid().hash(state); } } @@ -308,15 +331,11 @@ impl MonitorHandle { } pub(crate) fn ns_screen(&self, mtm: MainThreadMarker) -> Option> { - let uuid = unsafe { ffi::CGDisplayCreateUUIDFromDisplayID(self.0) }; + let uuid = self.uuid(); NSScreen::screens(mtm).into_iter().find(|screen| { let other_native_id = get_display_id(screen); - let other_uuid = unsafe { - ffi::CGDisplayCreateUUIDFromDisplayID( - other_native_id as CGDirectDisplayID, - ) - }; - uuid == other_uuid + let other = MonitorHandle::new(other_native_id); + uuid == other.uuid() }) } }