rio_window/platform/
macos.rs1use std::os::raw::c_void;
18
19use crate::event_loop::{ActiveEventLoop, EventLoopBuilder};
20use crate::monitor::MonitorHandle;
21use crate::window::{Window, WindowAttributes};
22
23pub trait WindowExtMacOS {
25 fn simple_fullscreen(&self) -> bool;
27
28 fn set_simple_fullscreen(&self, fullscreen: bool) -> bool;
36
37 fn has_shadow(&self) -> bool;
39
40 fn set_has_shadow(&self, has_shadow: bool);
42
43 fn set_background_color(&self, _r: f64, _g: f64, _b: f64, _a: f64);
45
46 fn set_tabbing_identifier(&self, identifier: &str);
50
51 fn tabbing_identifier(&self) -> String;
53
54 fn select_next_tab(&self);
56
57 fn select_previous_tab(&self);
59
60 fn select_tab_at_index(&self, index: usize);
64
65 fn num_tabs(&self) -> usize;
67
68 fn is_document_edited(&self) -> bool;
83
84 fn set_document_edited(&self, edited: bool);
86
87 fn set_option_as_alt(&self, option_as_alt: OptionAsAlt);
94
95 fn option_as_alt(&self) -> OptionAsAlt;
97
98 fn set_unified_titlebar(&self, unified_titlebar: bool);
101 fn unified_titlebar(&self) -> bool;
103}
104
105impl WindowExtMacOS for Window {
106 #[inline]
107 fn simple_fullscreen(&self) -> bool {
108 self.window.maybe_wait_on_main(|w| w.simple_fullscreen())
109 }
110
111 #[inline]
112 fn set_simple_fullscreen(&self, fullscreen: bool) -> bool {
113 self.window
114 .maybe_wait_on_main(move |w| w.set_simple_fullscreen(fullscreen))
115 }
116
117 #[inline]
118 fn has_shadow(&self) -> bool {
119 self.window.maybe_wait_on_main(|w| w.has_shadow())
120 }
121
122 #[inline]
123 fn set_has_shadow(&self, has_shadow: bool) {
124 self.window
125 .maybe_queue_on_main(move |w| w.set_has_shadow(has_shadow))
126 }
127
128 #[inline]
129 fn set_background_color(&self, r: f64, g: f64, b: f64, a: f64) {
130 self.window
131 .maybe_queue_on_main(move |w| w.set_background_color(r, g, b, a))
132 }
133
134 #[inline]
135 fn set_tabbing_identifier(&self, identifier: &str) {
136 self.window
137 .maybe_wait_on_main(|w| w.set_tabbing_identifier(identifier))
138 }
139
140 #[inline]
141 fn tabbing_identifier(&self) -> String {
142 self.window.maybe_wait_on_main(|w| w.tabbing_identifier())
143 }
144
145 #[inline]
146 fn select_next_tab(&self) {
147 self.window.maybe_queue_on_main(|w| w.select_next_tab())
148 }
149
150 #[inline]
151 fn select_previous_tab(&self) {
152 self.window.maybe_queue_on_main(|w| w.select_previous_tab())
153 }
154
155 #[inline]
156 fn select_tab_at_index(&self, index: usize) {
157 self.window
158 .maybe_queue_on_main(move |w| w.select_tab_at_index(index))
159 }
160
161 #[inline]
162 fn num_tabs(&self) -> usize {
163 self.window.maybe_wait_on_main(|w| w.num_tabs())
164 }
165
166 #[inline]
167 fn is_document_edited(&self) -> bool {
168 self.window.maybe_wait_on_main(|w| w.is_document_edited())
169 }
170
171 #[inline]
172 fn set_document_edited(&self, edited: bool) {
173 self.window
174 .maybe_queue_on_main(move |w| w.set_document_edited(edited))
175 }
176
177 #[inline]
178 fn set_option_as_alt(&self, option_as_alt: OptionAsAlt) {
179 self.window
180 .maybe_queue_on_main(move |w| w.set_option_as_alt(option_as_alt))
181 }
182
183 #[inline]
184 fn option_as_alt(&self) -> OptionAsAlt {
185 self.window.maybe_wait_on_main(|w| w.option_as_alt())
186 }
187
188 #[inline]
189 fn set_unified_titlebar(&self, unified_titlebar: bool) {
190 self.window
191 .maybe_wait_on_main(|w| w.set_unified_titlebar(unified_titlebar))
192 }
193
194 #[inline]
195 fn unified_titlebar(&self) -> bool {
196 self.window.maybe_wait_on_main(|w| w.unified_titlebar())
197 }
198}
199
200#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
202pub enum ActivationPolicy {
203 #[default]
205 Regular,
206
207 Accessory,
209
210 Prohibited,
212}
213
214pub trait WindowAttributesExtMacOS {
224 fn with_movable_by_window_background(
226 self,
227 movable_by_window_background: bool,
228 ) -> Self;
229 fn with_titlebar_transparent(self, titlebar_transparent: bool) -> Self;
231 fn with_title_hidden(self, title_hidden: bool) -> Self;
233 fn with_titlebar_hidden(self, titlebar_hidden: bool) -> Self;
235 fn with_titlebar_buttons_hidden(self, titlebar_buttons_hidden: bool) -> Self;
237 fn with_fullsize_content_view(self, fullsize_content_view: bool) -> Self;
239 fn with_disallow_hidpi(self, disallow_hidpi: bool) -> Self;
240 fn with_has_shadow(self, has_shadow: bool) -> Self;
241 fn with_accepts_first_mouse(self, accepts_first_mouse: bool) -> Self;
243 fn with_tabbing_identifier(self, identifier: &str) -> Self;
247 fn with_option_as_alt(self, option_as_alt: OptionAsAlt) -> Self;
251 fn with_unified_titlebar(self, unified_titlebar: bool) -> Self;
253}
254
255impl WindowAttributesExtMacOS for WindowAttributes {
256 #[inline]
257 fn with_movable_by_window_background(
258 mut self,
259 movable_by_window_background: bool,
260 ) -> Self {
261 self.platform_specific.movable_by_window_background =
262 movable_by_window_background;
263 self
264 }
265
266 #[inline]
267 fn with_titlebar_transparent(mut self, titlebar_transparent: bool) -> Self {
268 self.platform_specific.titlebar_transparent = titlebar_transparent;
269 self
270 }
271
272 #[inline]
273 fn with_titlebar_hidden(mut self, titlebar_hidden: bool) -> Self {
274 self.platform_specific.titlebar_hidden = titlebar_hidden;
275 self
276 }
277
278 #[inline]
279 fn with_titlebar_buttons_hidden(mut self, titlebar_buttons_hidden: bool) -> Self {
280 self.platform_specific.titlebar_buttons_hidden = titlebar_buttons_hidden;
281 self
282 }
283
284 #[inline]
285 fn with_title_hidden(mut self, title_hidden: bool) -> Self {
286 self.platform_specific.title_hidden = title_hidden;
287 self
288 }
289
290 #[inline]
291 fn with_fullsize_content_view(mut self, fullsize_content_view: bool) -> Self {
292 self.platform_specific.fullsize_content_view = fullsize_content_view;
293 self
294 }
295
296 #[inline]
297 fn with_disallow_hidpi(mut self, disallow_hidpi: bool) -> Self {
298 self.platform_specific.disallow_hidpi = disallow_hidpi;
299 self
300 }
301
302 #[inline]
303 fn with_has_shadow(mut self, has_shadow: bool) -> Self {
304 self.platform_specific.has_shadow = has_shadow;
305 self
306 }
307
308 #[inline]
309 fn with_accepts_first_mouse(mut self, accepts_first_mouse: bool) -> Self {
310 self.platform_specific.accepts_first_mouse = accepts_first_mouse;
311 self
312 }
313
314 #[inline]
315 fn with_tabbing_identifier(mut self, tabbing_identifier: &str) -> Self {
316 self.platform_specific
317 .tabbing_identifier
318 .replace(tabbing_identifier.to_string());
319 self
320 }
321
322 #[inline]
323 fn with_option_as_alt(mut self, option_as_alt: OptionAsAlt) -> Self {
324 self.platform_specific.option_as_alt = option_as_alt;
325 self
326 }
327
328 #[inline]
329 fn with_unified_titlebar(mut self, unified_titlebar: bool) -> Self {
330 self.platform_specific.unified_titlebar = unified_titlebar;
331 self
332 }
333}
334
335pub trait EventLoopBuilderExtMacOS {
336 fn with_activation_policy(
357 &mut self,
358 activation_policy: ActivationPolicy,
359 ) -> &mut Self;
360
361 fn with_default_menu(&mut self, enable: bool) -> &mut Self;
382
383 fn with_activate_ignoring_other_apps(&mut self, ignore: bool) -> &mut Self;
388}
389
390impl<T> EventLoopBuilderExtMacOS for EventLoopBuilder<T> {
391 #[inline]
392 fn with_activation_policy(
393 &mut self,
394 activation_policy: ActivationPolicy,
395 ) -> &mut Self {
396 self.platform_specific.activation_policy = activation_policy;
397 self
398 }
399
400 #[inline]
401 fn with_default_menu(&mut self, enable: bool) -> &mut Self {
402 self.platform_specific.default_menu = enable;
403 self
404 }
405
406 #[inline]
407 fn with_activate_ignoring_other_apps(&mut self, ignore: bool) -> &mut Self {
408 self.platform_specific.activate_ignoring_other_apps = ignore;
409 self
410 }
411}
412
413pub trait MonitorHandleExtMacOS {
415 fn native_id(&self) -> u32;
417 fn ns_screen(&self) -> Option<*mut c_void>;
419}
420
421impl MonitorHandleExtMacOS for MonitorHandle {
422 #[inline]
423 fn native_id(&self) -> u32 {
424 self.inner.native_identifier()
425 }
426
427 fn ns_screen(&self) -> Option<*mut c_void> {
428 let mtm = unsafe { objc2_foundation::MainThreadMarker::new_unchecked() };
430 self.inner
431 .ns_screen(mtm)
432 .map(|s| objc2::rc::Retained::as_ptr(&s) as _)
433 }
434}
435
436pub trait ActiveEventLoopExtMacOS {
438 fn hide_application(&self);
441 fn hide_other_applications(&self);
444 fn set_allows_automatic_window_tabbing(&self, enabled: bool);
448 fn allows_automatic_window_tabbing(&self) -> bool;
450}
451
452impl ActiveEventLoopExtMacOS for ActiveEventLoop {
453 fn hide_application(&self) {
454 self.p.hide_application()
455 }
456
457 fn hide_other_applications(&self) {
458 self.p.hide_other_applications()
459 }
460
461 fn set_allows_automatic_window_tabbing(&self, enabled: bool) {
462 self.p.set_allows_automatic_window_tabbing(enabled);
463 }
464
465 fn allows_automatic_window_tabbing(&self) -> bool {
466 self.p.allows_automatic_window_tabbing()
467 }
468}
469
470#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
474pub enum OptionAsAlt {
475 OnlyLeft,
477
478 OnlyRight,
480
481 Both,
483
484 #[default]
486 None,
487}