1#![cfg(target_os = "macos")]
2mod dispatcher;
8mod display;
9mod display_link;
10mod events;
11mod keyboard;
12mod pasteboard;
13mod system_notifications;
14
15#[cfg(feature = "screen-capture")]
16mod screen_capture;
17
18use gpui_apple::metal_renderer as renderer;
19
20pub mod metal_renderer {
21 pub use gpui_apple::metal_renderer::{PathRasterizationVertex, PathSprite, SurfaceBounds};
22
23 #[cfg(any(test, feature = "bench-support", feature = "test-support"))]
24 pub use gpui_apple::metal_renderer::MetalHeadlessRenderer;
25}
26
27pub use gpui_apple::imported_texture::MetalTextureExt;
30
31#[cfg(feature = "font-kit")]
32mod open_type;
33
34#[cfg(feature = "font-kit")]
35mod text_system;
36
37mod platform;
38mod window;
39mod window_appearance;
40
41use cocoa::{
42 base::{id, nil},
43 foundation::{NSAutoreleasePool, NSNotFound, NSString, NSUInteger},
44};
45
46use objc::runtime::{BOOL, NO, YES};
47use std::{
48 ffi::{CStr, c_char},
49 ops::Range,
50};
51
52pub(crate) use dispatcher::*;
53pub(crate) use display::*;
54pub(crate) use display_link::*;
55pub(crate) use keyboard::*;
56pub(crate) use platform::*;
57pub(crate) use window::*;
58
59#[cfg(feature = "font-kit")]
60pub(crate) use text_system::*;
61
62pub use platform::MacPlatform;
63
64trait BoolExt {
65 fn to_objc(self) -> BOOL;
66}
67
68impl BoolExt for bool {
69 fn to_objc(self) -> BOOL {
70 if self { YES } else { NO }
71 }
72}
73
74trait NSStringExt {
75 unsafe fn to_str(&self) -> &str;
76}
77
78impl NSStringExt for id {
79 unsafe fn to_str(&self) -> &str {
80 unsafe {
81 let cstr = self.UTF8String();
82 if cstr.is_null() {
83 ""
84 } else {
85 CStr::from_ptr(cstr as *mut c_char).to_str().unwrap()
86 }
87 }
88 }
89}
90
91#[repr(C)]
92#[derive(Copy, Clone, Debug)]
93struct NSRange {
94 pub location: NSUInteger,
95 pub length: NSUInteger,
96}
97
98impl NSRange {
99 fn invalid() -> Self {
100 Self {
101 location: NSNotFound as NSUInteger,
102 length: 0,
103 }
104 }
105
106 fn is_valid(&self) -> bool {
107 self.location != NSNotFound as NSUInteger
108 }
109
110 fn to_range(self) -> Option<Range<usize>> {
111 if self.is_valid() {
112 let start = self.location as usize;
113 let end = start + self.length as usize;
114 Some(start..end)
115 } else {
116 None
117 }
118 }
119}
120
121impl From<Range<usize>> for NSRange {
122 fn from(range: Range<usize>) -> Self {
123 NSRange {
124 location: range.start as NSUInteger,
125 length: range.len() as NSUInteger,
126 }
127 }
128}
129
130unsafe impl objc::Encode for NSRange {
131 fn encode() -> objc::Encoding {
132 let encoding = format!(
133 "{{NSRange={}{}}}",
134 NSUInteger::encode().as_str(),
135 NSUInteger::encode().as_str()
136 );
137 unsafe { objc::Encoding::from_str(&encoding) }
138 }
139}
140
141#[allow(clippy::disallowed_methods)]
143unsafe fn ns_string(string: &str) -> id {
144 unsafe { NSString::alloc(nil).init_str(string).autorelease() }
145}