1 #![cfg(target_os = "macos")]
2 
3 use std::os::raw::c_void;
4 use {LogicalSize, MonitorId, Window, WindowBuilder};
5 
6 /// Additional methods on `Window` that are specific to MacOS.
7 pub trait WindowExt {
8     /// Returns a pointer to the cocoa `NSWindow` that is used by this window.
9     ///
10     /// The pointer will become invalid when the `Window` is destroyed.
get_nswindow(&self) -> *mut c_void11     fn get_nswindow(&self) -> *mut c_void;
12 
13     /// Returns a pointer to the cocoa `NSView` that is used by this window.
14     ///
15     /// The pointer will become invalid when the `Window` is destroyed.
get_nsview(&self) -> *mut c_void16     fn get_nsview(&self) -> *mut c_void;
17 
18     /// Request user attention, causing the application's dock icon to bounce.
19     /// Note that this has no effect if the application is already focused.
20     ///
21     /// The `is_critical` flag has the following effects:
22     /// - `false`: the dock icon will only bounce once.
23     /// - `true`: the dock icon will bounce until the application is focused.
request_user_attention(&self, is_critical: bool)24     fn request_user_attention(&self, is_critical: bool);
25 
26     /// Returns whether or not the window is in simple fullscreen mode.
get_simple_fullscreen(&self) -> bool27     fn get_simple_fullscreen(&self) -> bool;
28 
29     /// Toggles a fullscreen mode that doesn't require a new macOS space.
30     /// Returns a boolean indicating whether the transition was successful (this
31     /// won't work if the window was already in the native fullscreen).
32     ///
33     /// This is how fullscreen used to work on macOS in versions before Lion.
34     /// And allows the user to have a fullscreen window without using another
35     /// space or taking control over the entire monitor.
set_simple_fullscreen(&self, fullscreen: bool) -> bool36     fn set_simple_fullscreen(&self, fullscreen: bool) -> bool;
37 }
38 
39 impl WindowExt for Window {
40     #[inline]
get_nswindow(&self) -> *mut c_void41     fn get_nswindow(&self) -> *mut c_void {
42         self.window.get_nswindow()
43     }
44 
45     #[inline]
get_nsview(&self) -> *mut c_void46     fn get_nsview(&self) -> *mut c_void {
47         self.window.get_nsview()
48     }
49 
50     #[inline]
request_user_attention(&self, is_critical: bool)51     fn request_user_attention(&self, is_critical: bool) {
52         self.window.request_user_attention(is_critical)
53     }
54 
55     #[inline]
get_simple_fullscreen(&self) -> bool56     fn get_simple_fullscreen(&self) -> bool {
57         self.window.get_simple_fullscreen()
58     }
59 
60     #[inline]
set_simple_fullscreen(&self, fullscreen: bool) -> bool61     fn set_simple_fullscreen(&self, fullscreen: bool) -> bool {
62         self.window.set_simple_fullscreen(fullscreen)
63     }
64 }
65 
66 /// Corresponds to `NSApplicationActivationPolicy`.
67 #[derive(Debug, Clone, Copy, PartialEq)]
68 pub enum ActivationPolicy {
69     /// Corresponds to `NSApplicationActivationPolicyRegular`.
70     Regular,
71     /// Corresponds to `NSApplicationActivationPolicyAccessory`.
72     Accessory,
73     /// Corresponds to `NSApplicationActivationPolicyProhibited`.
74     Prohibited,
75 }
76 
77 impl Default for ActivationPolicy {
default() -> Self78     fn default() -> Self {
79         ActivationPolicy::Regular
80     }
81 }
82 
83 /// Additional methods on `WindowBuilder` that are specific to MacOS.
84 ///
85 /// **Note:** Properties dealing with the titlebar will be overwritten by the `with_decorations` method
86 /// on the base `WindowBuilder`:
87 ///
88 ///  - `with_titlebar_transparent`
89 ///  - `with_title_hidden`
90 ///  - `with_titlebar_hidden`
91 ///  - `with_titlebar_buttons_hidden`
92 ///  - `with_fullsize_content_view`
93 pub trait WindowBuilderExt {
94     /// Sets the activation policy for the window being built.
with_activation_policy(self, activation_policy: ActivationPolicy) -> WindowBuilder95     fn with_activation_policy(self, activation_policy: ActivationPolicy) -> WindowBuilder;
96     /// Enables click-and-drag behavior for the entire window, not just the titlebar.
with_movable_by_window_background(self, movable_by_window_background: bool) -> WindowBuilder97     fn with_movable_by_window_background(self, movable_by_window_background: bool) -> WindowBuilder;
98     /// Makes the titlebar transparent and allows the content to appear behind it.
with_titlebar_transparent(self, titlebar_transparent: bool) -> WindowBuilder99     fn with_titlebar_transparent(self, titlebar_transparent: bool) -> WindowBuilder;
100     /// Hides the window title.
with_title_hidden(self, title_hidden: bool) -> WindowBuilder101     fn with_title_hidden(self, title_hidden: bool) -> WindowBuilder;
102     /// Hides the window titlebar.
with_titlebar_hidden(self, titlebar_hidden: bool) -> WindowBuilder103     fn with_titlebar_hidden(self, titlebar_hidden: bool) -> WindowBuilder;
104     /// Hides the window titlebar buttons.
with_titlebar_buttons_hidden(self, titlebar_buttons_hidden: bool) -> WindowBuilder105     fn with_titlebar_buttons_hidden(self, titlebar_buttons_hidden: bool) -> WindowBuilder;
106     /// Makes the window content appear behind the titlebar.
with_fullsize_content_view(self, fullsize_content_view: bool) -> WindowBuilder107     fn with_fullsize_content_view(self, fullsize_content_view: bool) -> WindowBuilder;
108     /// Build window with `resizeIncrements` property. Values must not be 0.
with_resize_increments(self, increments: LogicalSize) -> WindowBuilder109     fn with_resize_increments(self, increments: LogicalSize) -> WindowBuilder;
110 }
111 
112 impl WindowBuilderExt for WindowBuilder {
113     #[inline]
with_activation_policy(mut self, activation_policy: ActivationPolicy) -> WindowBuilder114     fn with_activation_policy(mut self, activation_policy: ActivationPolicy) -> WindowBuilder {
115         self.platform_specific.activation_policy = activation_policy;
116         self
117     }
118 
119     #[inline]
with_movable_by_window_background(mut self, movable_by_window_background: bool) -> WindowBuilder120     fn with_movable_by_window_background(mut self, movable_by_window_background: bool) -> WindowBuilder {
121         self.platform_specific.movable_by_window_background = movable_by_window_background;
122         self
123     }
124 
125     #[inline]
with_titlebar_transparent(mut self, titlebar_transparent: bool) -> WindowBuilder126     fn with_titlebar_transparent(mut self, titlebar_transparent: bool) -> WindowBuilder {
127         self.platform_specific.titlebar_transparent = titlebar_transparent;
128         self
129     }
130 
131     #[inline]
with_titlebar_hidden(mut self, titlebar_hidden: bool) -> WindowBuilder132     fn with_titlebar_hidden(mut self, titlebar_hidden: bool) -> WindowBuilder {
133         self.platform_specific.titlebar_hidden = titlebar_hidden;
134         self
135     }
136 
137     #[inline]
with_titlebar_buttons_hidden(mut self, titlebar_buttons_hidden: bool) -> WindowBuilder138     fn with_titlebar_buttons_hidden(mut self, titlebar_buttons_hidden: bool) -> WindowBuilder {
139         self.platform_specific.titlebar_buttons_hidden = titlebar_buttons_hidden;
140         self
141     }
142 
143     #[inline]
with_title_hidden(mut self, title_hidden: bool) -> WindowBuilder144     fn with_title_hidden(mut self, title_hidden: bool) -> WindowBuilder {
145         self.platform_specific.title_hidden = title_hidden;
146         self
147     }
148 
149     #[inline]
with_fullsize_content_view(mut self, fullsize_content_view: bool) -> WindowBuilder150     fn with_fullsize_content_view(mut self, fullsize_content_view: bool) -> WindowBuilder {
151         self.platform_specific.fullsize_content_view = fullsize_content_view;
152         self
153     }
154 
155     #[inline]
with_resize_increments(mut self, increments: LogicalSize) -> WindowBuilder156     fn with_resize_increments(mut self, increments: LogicalSize) -> WindowBuilder {
157         self.platform_specific.resize_increments = Some(increments.into());
158         self
159     }
160 }
161 
162 /// Additional methods on `MonitorId` that are specific to MacOS.
163 pub trait MonitorIdExt {
164     /// Returns the identifier of the monitor for Cocoa.
native_id(&self) -> u32165     fn native_id(&self) -> u32;
166     /// Returns a pointer to the NSScreen representing this monitor.
get_nsscreen(&self) -> Option<*mut c_void>167     fn get_nsscreen(&self) -> Option<*mut c_void>;
168 }
169 
170 impl MonitorIdExt for MonitorId {
171     #[inline]
native_id(&self) -> u32172     fn native_id(&self) -> u32 {
173         self.inner.get_native_identifier()
174     }
175 
get_nsscreen(&self) -> Option<*mut c_void>176     fn get_nsscreen(&self) -> Option<*mut c_void> {
177         self.inner.get_nsscreen().map(|s| s as *mut c_void)
178     }
179 }
180