2016-01-17 10:12:21 +11:00
|
|
|
#![cfg(target_os = "macos")]
|
|
|
|
|
|
|
|
use std::os::raw::c_void;
|
2019-05-02 09:03:30 +10:00
|
|
|
|
2019-06-22 01:33:15 +10:00
|
|
|
use crate::{
|
|
|
|
dpi::LogicalSize,
|
2021-04-30 19:31:28 +10:00
|
|
|
event_loop::{EventLoop, EventLoopWindowTarget},
|
2019-06-22 01:33:15 +10:00
|
|
|
monitor::MonitorHandle,
|
2021-04-30 19:31:28 +10:00
|
|
|
platform_impl::get_aux_state_mut,
|
2019-06-22 01:33:15 +10:00
|
|
|
window::{Window, WindowBuilder},
|
|
|
|
};
|
2016-01-17 10:12:21 +11:00
|
|
|
|
|
|
|
/// Additional methods on `Window` that are specific to MacOS.
|
2019-02-06 02:30:33 +11:00
|
|
|
pub trait WindowExtMacOS {
|
2016-01-17 10:12:21 +11:00
|
|
|
/// Returns a pointer to the cocoa `NSWindow` that is used by this window.
|
|
|
|
///
|
2016-10-07 03:58:15 +11:00
|
|
|
/// The pointer will become invalid when the `Window` is destroyed.
|
2019-06-11 09:09:38 +10:00
|
|
|
fn ns_window(&self) -> *mut c_void;
|
2016-01-17 10:12:21 +11:00
|
|
|
|
2016-10-07 03:58:15 +11:00
|
|
|
/// Returns a pointer to the cocoa `NSView` that is used by this window.
|
|
|
|
///
|
|
|
|
/// The pointer will become invalid when the `Window` is destroyed.
|
2019-06-11 09:09:38 +10:00
|
|
|
fn ns_view(&self) -> *mut c_void;
|
2018-11-07 15:50:40 +11:00
|
|
|
|
2019-04-26 03:09:32 +10:00
|
|
|
/// Returns whether or not the window is in simple fullscreen mode.
|
2019-05-30 11:29:54 +10:00
|
|
|
fn simple_fullscreen(&self) -> bool;
|
2019-04-26 03:09:32 +10:00
|
|
|
|
2018-12-19 15:07:33 +11:00
|
|
|
/// Toggles a fullscreen mode that doesn't require a new macOS space.
|
|
|
|
/// Returns a boolean indicating whether the transition was successful (this
|
|
|
|
/// won't work if the window was already in the native fullscreen).
|
|
|
|
///
|
|
|
|
/// This is how fullscreen used to work on macOS in versions before Lion.
|
|
|
|
/// And allows the user to have a fullscreen window without using another
|
|
|
|
/// space or taking control over the entire monitor.
|
|
|
|
fn set_simple_fullscreen(&self, fullscreen: bool) -> bool;
|
2020-08-14 04:10:34 +10:00
|
|
|
|
|
|
|
/// Returns whether or not the window has shadow.
|
|
|
|
fn has_shadow(&self) -> bool;
|
|
|
|
|
|
|
|
/// Sets whether or not the window has shadow.
|
|
|
|
fn set_has_shadow(&self, has_shadow: bool);
|
2016-01-17 10:12:21 +11:00
|
|
|
}
|
2016-04-29 09:30:44 +10:00
|
|
|
|
2019-02-06 02:30:33 +11:00
|
|
|
impl WindowExtMacOS for Window {
|
2016-10-08 18:18:00 +11:00
|
|
|
#[inline]
|
2019-06-11 09:09:38 +10:00
|
|
|
fn ns_window(&self) -> *mut c_void {
|
|
|
|
self.window.ns_window()
|
2016-10-08 18:18:00 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2019-06-11 09:09:38 +10:00
|
|
|
fn ns_view(&self) -> *mut c_void {
|
|
|
|
self.window.ns_view()
|
2016-10-08 18:18:00 +11:00
|
|
|
}
|
2018-11-07 15:50:40 +11:00
|
|
|
|
2019-04-26 03:09:32 +10:00
|
|
|
#[inline]
|
2019-05-30 11:29:54 +10:00
|
|
|
fn simple_fullscreen(&self) -> bool {
|
|
|
|
self.window.simple_fullscreen()
|
2019-04-26 03:09:32 +10:00
|
|
|
}
|
|
|
|
|
2018-12-19 15:07:33 +11:00
|
|
|
#[inline]
|
|
|
|
fn set_simple_fullscreen(&self, fullscreen: bool) -> bool {
|
|
|
|
self.window.set_simple_fullscreen(fullscreen)
|
|
|
|
}
|
2020-08-14 04:10:34 +10:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn has_shadow(&self) -> bool {
|
|
|
|
self.window.has_shadow()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn set_has_shadow(&self, has_shadow: bool) {
|
|
|
|
self.window.set_has_shadow(has_shadow)
|
|
|
|
}
|
2016-10-08 18:18:00 +11:00
|
|
|
}
|
|
|
|
|
2016-04-29 09:30:44 +10:00
|
|
|
/// Corresponds to `NSApplicationActivationPolicy`.
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
|
|
|
pub enum ActivationPolicy {
|
|
|
|
/// Corresponds to `NSApplicationActivationPolicyRegular`.
|
|
|
|
Regular,
|
|
|
|
/// Corresponds to `NSApplicationActivationPolicyAccessory`.
|
|
|
|
Accessory,
|
|
|
|
/// Corresponds to `NSApplicationActivationPolicyProhibited`.
|
|
|
|
Prohibited,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for ActivationPolicy {
|
|
|
|
fn default() -> Self {
|
|
|
|
ActivationPolicy::Regular
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Additional methods on `WindowBuilder` that are specific to MacOS.
|
2018-03-23 03:57:35 +11:00
|
|
|
///
|
|
|
|
/// **Note:** Properties dealing with the titlebar will be overwritten by the `with_decorations` method
|
|
|
|
/// on the base `WindowBuilder`:
|
|
|
|
///
|
|
|
|
/// - `with_titlebar_transparent`
|
|
|
|
/// - `with_title_hidden`
|
|
|
|
/// - `with_titlebar_hidden`
|
|
|
|
/// - `with_titlebar_buttons_hidden`
|
|
|
|
/// - `with_fullsize_content_view`
|
2019-02-06 02:30:33 +11:00
|
|
|
pub trait WindowBuilderExtMacOS {
|
2018-05-17 00:16:36 +10:00
|
|
|
/// Enables click-and-drag behavior for the entire window, not just the titlebar.
|
2019-06-22 01:33:15 +10:00
|
|
|
fn with_movable_by_window_background(self, movable_by_window_background: bool)
|
|
|
|
-> WindowBuilder;
|
2018-05-17 00:16:36 +10:00
|
|
|
/// Makes the titlebar transparent and allows the content to appear behind it.
|
2018-03-23 03:57:35 +11:00
|
|
|
fn with_titlebar_transparent(self, titlebar_transparent: bool) -> WindowBuilder;
|
2018-05-17 00:16:36 +10:00
|
|
|
/// Hides the window title.
|
2018-03-23 03:57:35 +11:00
|
|
|
fn with_title_hidden(self, title_hidden: bool) -> WindowBuilder;
|
2018-05-17 00:16:36 +10:00
|
|
|
/// Hides the window titlebar.
|
2018-03-23 03:57:35 +11:00
|
|
|
fn with_titlebar_hidden(self, titlebar_hidden: bool) -> WindowBuilder;
|
2018-05-17 00:16:36 +10:00
|
|
|
/// Hides the window titlebar buttons.
|
2018-03-23 03:57:35 +11:00
|
|
|
fn with_titlebar_buttons_hidden(self, titlebar_buttons_hidden: bool) -> WindowBuilder;
|
2018-05-17 00:16:36 +10:00
|
|
|
/// Makes the window content appear behind the titlebar.
|
2018-03-23 03:57:35 +11:00
|
|
|
fn with_fullsize_content_view(self, fullsize_content_view: bool) -> WindowBuilder;
|
2018-05-17 00:16:36 +10:00
|
|
|
/// Build window with `resizeIncrements` property. Values must not be 0.
|
2020-01-04 17:33:07 +11:00
|
|
|
fn with_resize_increments(self, increments: LogicalSize<f64>) -> WindowBuilder;
|
2019-07-29 18:07:36 +10:00
|
|
|
fn with_disallow_hidpi(self, disallow_hidpi: bool) -> WindowBuilder;
|
2020-08-14 04:10:34 +10:00
|
|
|
fn with_has_shadow(self, has_shadow: bool) -> WindowBuilder;
|
2016-04-29 09:30:44 +10:00
|
|
|
}
|
|
|
|
|
2019-02-06 02:30:33 +11:00
|
|
|
impl WindowBuilderExtMacOS for WindowBuilder {
|
2018-01-23 05:07:51 +11:00
|
|
|
#[inline]
|
2019-06-22 01:33:15 +10:00
|
|
|
fn with_movable_by_window_background(
|
|
|
|
mut self,
|
|
|
|
movable_by_window_background: bool,
|
|
|
|
) -> WindowBuilder {
|
2018-01-23 05:07:51 +11:00
|
|
|
self.platform_specific.movable_by_window_background = movable_by_window_background;
|
|
|
|
self
|
|
|
|
}
|
2018-03-23 03:57:35 +11:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn with_titlebar_transparent(mut self, titlebar_transparent: bool) -> WindowBuilder {
|
|
|
|
self.platform_specific.titlebar_transparent = titlebar_transparent;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn with_titlebar_hidden(mut self, titlebar_hidden: bool) -> WindowBuilder {
|
|
|
|
self.platform_specific.titlebar_hidden = titlebar_hidden;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn with_titlebar_buttons_hidden(mut self, titlebar_buttons_hidden: bool) -> WindowBuilder {
|
|
|
|
self.platform_specific.titlebar_buttons_hidden = titlebar_buttons_hidden;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn with_title_hidden(mut self, title_hidden: bool) -> WindowBuilder {
|
|
|
|
self.platform_specific.title_hidden = title_hidden;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn with_fullsize_content_view(mut self, fullsize_content_view: bool) -> WindowBuilder {
|
|
|
|
self.platform_specific.fullsize_content_view = fullsize_content_view;
|
|
|
|
self
|
|
|
|
}
|
2018-05-17 00:16:36 +10:00
|
|
|
|
|
|
|
#[inline]
|
2020-01-04 17:33:07 +11:00
|
|
|
fn with_resize_increments(mut self, increments: LogicalSize<f64>) -> WindowBuilder {
|
2018-06-15 09:42:18 +10:00
|
|
|
self.platform_specific.resize_increments = Some(increments.into());
|
2018-05-17 00:16:36 +10:00
|
|
|
self
|
|
|
|
}
|
2019-07-29 18:07:36 +10:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn with_disallow_hidpi(mut self, disallow_hidpi: bool) -> WindowBuilder {
|
|
|
|
self.platform_specific.disallow_hidpi = disallow_hidpi;
|
|
|
|
self
|
|
|
|
}
|
2020-08-14 04:10:34 +10:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn with_has_shadow(mut self, has_shadow: bool) -> WindowBuilder {
|
|
|
|
self.platform_specific.has_shadow = has_shadow;
|
|
|
|
self
|
|
|
|
}
|
2016-04-29 09:30:44 +10:00
|
|
|
}
|
2017-08-30 16:49:18 +10:00
|
|
|
|
2021-04-30 19:31:28 +10:00
|
|
|
pub trait EventLoopExtMacOS {
|
|
|
|
/// Sets the activation policy for the application. It is set to
|
|
|
|
/// `NSApplicationActivationPolicyRegular` by default.
|
|
|
|
///
|
|
|
|
/// This function only takes effect if it's called before calling [`run`](crate::event_loop::EventLoop::run) or
|
|
|
|
/// [`run_return`](crate::platform::run_return::EventLoopExtRunReturn::run_return)
|
|
|
|
fn set_activation_policy(&mut self, activation_policy: ActivationPolicy);
|
|
|
|
}
|
|
|
|
impl<T> EventLoopExtMacOS for EventLoop<T> {
|
|
|
|
#[inline]
|
|
|
|
fn set_activation_policy(&mut self, activation_policy: ActivationPolicy) {
|
|
|
|
unsafe {
|
|
|
|
get_aux_state_mut(&**self.event_loop.delegate).activation_policy = activation_policy;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-06 02:30:33 +11:00
|
|
|
/// Additional methods on `MonitorHandle` that are specific to MacOS.
|
|
|
|
pub trait MonitorHandleExtMacOS {
|
2017-08-30 16:49:18 +10:00
|
|
|
/// Returns the identifier of the monitor for Cocoa.
|
|
|
|
fn native_id(&self) -> u32;
|
2018-03-06 19:35:04 +11:00
|
|
|
/// Returns a pointer to the NSScreen representing this monitor.
|
2019-06-11 09:09:38 +10:00
|
|
|
fn ns_screen(&self) -> Option<*mut c_void>;
|
2017-08-30 16:49:18 +10:00
|
|
|
}
|
|
|
|
|
2019-02-06 02:30:33 +11:00
|
|
|
impl MonitorHandleExtMacOS for MonitorHandle {
|
2017-08-30 16:49:18 +10:00
|
|
|
#[inline]
|
|
|
|
fn native_id(&self) -> u32 {
|
2019-05-30 11:29:54 +10:00
|
|
|
self.inner.native_identifier()
|
2017-08-30 16:49:18 +10:00
|
|
|
}
|
2018-03-06 19:35:04 +11:00
|
|
|
|
2019-06-11 09:09:38 +10:00
|
|
|
fn ns_screen(&self) -> Option<*mut c_void> {
|
|
|
|
self.inner.ns_screen().map(|s| s as *mut c_void)
|
2018-03-06 19:35:04 +11:00
|
|
|
}
|
2017-08-30 16:49:18 +10:00
|
|
|
}
|
2020-01-20 10:38:52 +11:00
|
|
|
|
|
|
|
/// Additional methods on `EventLoopWindowTarget` that are specific to macOS.
|
|
|
|
pub trait EventLoopWindowTargetExtMacOS {
|
|
|
|
/// Hide the entire application. In most applications this is typically triggered with Command-H.
|
|
|
|
fn hide_application(&self);
|
2020-05-25 02:26:29 +10:00
|
|
|
/// Hide the other applications. In most applications this is typically triggered with Command+Option-H.
|
|
|
|
fn hide_other_applications(&self);
|
2020-01-20 10:38:52 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> EventLoopWindowTargetExtMacOS for EventLoopWindowTarget<T> {
|
|
|
|
fn hide_application(&self) {
|
|
|
|
let cls = objc::runtime::Class::get("NSApplication").unwrap();
|
|
|
|
let app: cocoa::base::id = unsafe { msg_send![cls, sharedApplication] };
|
|
|
|
unsafe { msg_send![app, hide: 0] }
|
|
|
|
}
|
2020-05-25 02:26:29 +10:00
|
|
|
|
|
|
|
fn hide_other_applications(&self) {
|
|
|
|
let cls = objc::runtime::Class::get("NSApplication").unwrap();
|
|
|
|
let app: cocoa::base::id = unsafe { msg_send![cls, sharedApplication] };
|
|
|
|
unsafe { msg_send![app, hideOtherApplications: 0] }
|
|
|
|
}
|
2020-01-20 10:38:52 +11:00
|
|
|
}
|