* Remove executable flag from os/macos.rs This was causing me some grief while working on Windows, and it doesn't belong here to begin with. * Windows: get_position returns screen coordinates instead of workspace coordinates Previously, get_position used GetWindowPlacement. As per the documentation of WINDOWSTRUCT, the returned coordinates are in workspace space, meaning they're relative to the taskbar. It's also explicitly remarked that these coordinates should only be used in conjunction with SetWindowPlacement, as mixing them with functions expecting screen coordinates can cause unpleasantness. Since our set_position (correctly) uses SetWindowPos, this meant that passing the return of get_position to set_position would cause the window to move. We now use GetWindowRect, which returns screen coordinates. This gives us both better consistency within the Windows backend and across platforms. Note that this only makes a difference if the taskbar is visible. With the taskbar hidden, the values are exactly the same as before. * Windows: Moved event position values are consistent with get_position The old Moved values had two problems: * They were obtained by casting a WORD (u16) straight to an i32. This meant wrap-around would never be interpreted as negative, thus negative positions (which are ubiquitous when using multiple monitors) would result in positions around u16::MAX. * WM_MOVE supplies client area positions, not window positions. Switching to handling WM_WINDOWPOSCHANGED solves both of these problems. * Better documentation for Moved and Resized
151 lines
5.2 KiB
Rust
151 lines
5.2 KiB
Rust
#![cfg(target_os = "macos")]
|
|
|
|
use std::convert::From;
|
|
use std::os::raw::c_void;
|
|
use cocoa::appkit::NSApplicationActivationPolicy;
|
|
use {MonitorId, Window, WindowBuilder};
|
|
|
|
/// Additional methods on `Window` that are specific to MacOS.
|
|
pub trait WindowExt {
|
|
/// Returns a pointer to the cocoa `NSWindow` that is used by this window.
|
|
///
|
|
/// The pointer will become invalid when the `Window` is destroyed.
|
|
fn get_nswindow(&self) -> *mut c_void;
|
|
|
|
/// Returns a pointer to the cocoa `NSView` that is used by this window.
|
|
///
|
|
/// The pointer will become invalid when the `Window` is destroyed.
|
|
fn get_nsview(&self) -> *mut c_void;
|
|
}
|
|
|
|
impl WindowExt for Window {
|
|
#[inline]
|
|
fn get_nswindow(&self) -> *mut c_void {
|
|
self.window.get_nswindow()
|
|
}
|
|
|
|
#[inline]
|
|
fn get_nsview(&self) -> *mut c_void {
|
|
self.window.get_nsview()
|
|
}
|
|
}
|
|
|
|
/// 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
|
|
}
|
|
}
|
|
|
|
impl From<ActivationPolicy> for NSApplicationActivationPolicy {
|
|
fn from(activation_policy: ActivationPolicy) -> Self {
|
|
match activation_policy {
|
|
ActivationPolicy::Regular =>
|
|
NSApplicationActivationPolicy::NSApplicationActivationPolicyRegular,
|
|
ActivationPolicy::Accessory =>
|
|
NSApplicationActivationPolicy::NSApplicationActivationPolicyAccessory,
|
|
ActivationPolicy::Prohibited =>
|
|
NSApplicationActivationPolicy::NSApplicationActivationPolicyProhibited,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Additional methods on `WindowBuilder` that are specific to MacOS.
|
|
///
|
|
/// **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`
|
|
pub trait WindowBuilderExt {
|
|
fn with_activation_policy(self, activation_policy: ActivationPolicy) -> WindowBuilder;
|
|
fn with_movable_by_window_background(self, movable_by_window_background: bool) -> WindowBuilder;
|
|
fn with_titlebar_transparent(self, titlebar_transparent: bool) -> WindowBuilder;
|
|
fn with_title_hidden(self, title_hidden: bool) -> WindowBuilder;
|
|
fn with_titlebar_hidden(self, titlebar_hidden: bool) -> WindowBuilder;
|
|
fn with_titlebar_buttons_hidden(self, titlebar_buttons_hidden: bool) -> WindowBuilder;
|
|
fn with_fullsize_content_view(self, fullsize_content_view: bool) -> WindowBuilder;
|
|
}
|
|
|
|
impl WindowBuilderExt for WindowBuilder {
|
|
/// Sets the activation policy for the window being built
|
|
#[inline]
|
|
fn with_activation_policy(mut self, activation_policy: ActivationPolicy) -> WindowBuilder {
|
|
self.platform_specific.activation_policy = activation_policy;
|
|
self
|
|
}
|
|
|
|
/// Enables click-and-drag behavior for the entire window, not just the titlebar
|
|
#[inline]
|
|
fn with_movable_by_window_background(mut self, movable_by_window_background: bool) -> WindowBuilder {
|
|
self.platform_specific.movable_by_window_background = movable_by_window_background;
|
|
self
|
|
}
|
|
|
|
/// Makes the titlebar transparent and allows the content to appear behind it
|
|
#[inline]
|
|
fn with_titlebar_transparent(mut self, titlebar_transparent: bool) -> WindowBuilder {
|
|
self.platform_specific.titlebar_transparent = titlebar_transparent;
|
|
self
|
|
}
|
|
|
|
/// Hides the window titlebar
|
|
#[inline]
|
|
fn with_titlebar_hidden(mut self, titlebar_hidden: bool) -> WindowBuilder {
|
|
self.platform_specific.titlebar_hidden = titlebar_hidden;
|
|
self
|
|
}
|
|
|
|
/// Hides the window titlebar buttons
|
|
#[inline]
|
|
fn with_titlebar_buttons_hidden(mut self, titlebar_buttons_hidden: bool) -> WindowBuilder {
|
|
self.platform_specific.titlebar_buttons_hidden = titlebar_buttons_hidden;
|
|
self
|
|
}
|
|
|
|
/// Hides the window title
|
|
#[inline]
|
|
fn with_title_hidden(mut self, title_hidden: bool) -> WindowBuilder {
|
|
self.platform_specific.title_hidden = title_hidden;
|
|
self
|
|
}
|
|
|
|
/// Makes the window content appear behind the titlebar
|
|
#[inline]
|
|
fn with_fullsize_content_view(mut self, fullsize_content_view: bool) -> WindowBuilder {
|
|
self.platform_specific.fullsize_content_view = fullsize_content_view;
|
|
self
|
|
}
|
|
}
|
|
|
|
/// Additional methods on `MonitorId` that are specific to MacOS.
|
|
pub trait MonitorIdExt {
|
|
/// Returns the identifier of the monitor for Cocoa.
|
|
fn native_id(&self) -> u32;
|
|
/// Returns a pointer to the NSScreen representing this monitor.
|
|
fn get_nsscreen(&self) -> Option<*mut c_void>;
|
|
}
|
|
|
|
impl MonitorIdExt for MonitorId {
|
|
#[inline]
|
|
fn native_id(&self) -> u32 {
|
|
self.inner.get_native_identifier()
|
|
}
|
|
|
|
fn get_nsscreen(&self) -> Option<*mut c_void> {
|
|
self.inner.get_nsscreen().map(|s| s as *mut c_void)
|
|
}
|
|
}
|