1#![cfg(target_os = "macos")]
2mod display;
8mod display_link;
9mod events;
10mod keyboard;
11mod pasteboard;
12mod system_notifications;
13
14#[cfg(feature = "screen-capture")]
15mod screen_capture;
16
17use gpui_apple::metal_renderer as renderer;
18
19pub mod metal_renderer {
20 pub use gpui_apple::metal_renderer::{PathRasterizationVertex, PathSprite, SurfaceBounds};
21
22 #[cfg(any(test, feature = "bench-support", feature = "test-support"))]
23 pub use gpui_apple::metal_renderer::MetalHeadlessRenderer;
24}
25
26mod platform;
27mod window;
28mod window_appearance;
29
30use objc2::{
31 Encode, Encoding, RefEncode,
32 rc::Retained,
33 runtime::{AnyObject, Bool},
34};
35use objc2_foundation::{NSNotFound, NSString, NSUInteger};
36use std::{ffi::CStr, ops::Range};
37
38pub(crate) use display::*;
39pub(crate) use display_link::*;
40pub(crate) use gpui_apple::{AppleActivity, AppleDispatcher, main_thread_marker};
41pub(crate) use keyboard::*;
42pub(crate) use platform::*;
43pub(crate) use window::*;
44
45pub use platform::MacPlatform;
46
47trait BoolExt {
48 fn to_objc(self) -> Bool;
49}
50
51impl BoolExt for bool {
52 fn to_objc(self) -> Bool {
53 Bool::new(self)
54 }
55}
56
57trait NSStringExt {
58 unsafe fn to_str(&self) -> &str;
59}
60
61impl NSStringExt for *mut AnyObject {
62 unsafe fn to_str(&self) -> &str {
63 unsafe {
64 let Some(string) = self.cast::<NSString>().as_ref() else {
65 return "";
66 };
67 let cstr = string.UTF8String();
68 if cstr.is_null() {
69 ""
70 } else {
71 CStr::from_ptr(cstr).to_str().unwrap()
72 }
73 }
74 }
75}
76
77#[repr(C)]
78#[derive(Copy, Clone, Debug)]
79struct NSRange {
80 pub location: NSUInteger,
81 pub length: NSUInteger,
82}
83
84impl NSRange {
85 fn invalid() -> Self {
86 Self {
87 location: NSNotFound as NSUInteger,
88 length: 0,
89 }
90 }
91
92 fn is_valid(&self) -> bool {
93 self.location != NSNotFound as NSUInteger
94 }
95
96 fn to_range(self) -> Option<Range<usize>> {
97 if self.is_valid() {
98 let start = self.location;
99 let end = start + self.length;
100 Some(start..end)
101 } else {
102 None
103 }
104 }
105}
106
107impl From<Range<usize>> for NSRange {
108 fn from(range: Range<usize>) -> Self {
109 NSRange {
110 location: range.start as NSUInteger,
111 length: range.len() as NSUInteger,
112 }
113 }
114}
115
116unsafe impl Encode for NSRange {
117 const ENCODING: Encoding = objc2_foundation::NSRange::ENCODING;
118}
119
120unsafe impl RefEncode for NSRange {
121 const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
122}
123
124fn ns_string(string: &str) -> *mut AnyObject {
125 Retained::autorelease_ptr(NSString::from_str(string)).cast()
126}