Refactor macOS to use new objc2 features (#2465)
* Remove UnownedWindow::inner_rect * Refactor custom view to use much less `unsafe` The compiler fence is safe to get rid of now since `interpretKeyEvents` takes `&mut self` * Refactor Window to use much less unsafe * Refactor NSApplication usage to have much less unsafe * Remove cocoa dependency * Enable `deny(unsafe_op_in_unsafe_fn)` on macOS Also re-enable clippy `let_unit_value` lint * Remove #[macro_use] on macOS * Refactor window delegate to use much less unsafe
This commit is contained in:
parent
05dd31b8ea
commit
340f951d10
34 changed files with 2756 additions and 2335 deletions
|
|
@ -1,7 +1,10 @@
|
|||
use objc2::foundation::NSObject;
|
||||
use objc2::{extern_class, ClassType};
|
||||
use objc2::foundation::{MainThreadMarker, NSArray, NSInteger, NSObject, NSUInteger};
|
||||
use objc2::rc::{Id, Shared};
|
||||
use objc2::runtime::Object;
|
||||
use objc2::{extern_class, extern_methods, msg_send_id, ClassType};
|
||||
use objc2::{Encode, Encoding};
|
||||
|
||||
use super::NSResponder;
|
||||
use super::{NSEvent, NSMenu, NSResponder, NSWindow};
|
||||
|
||||
extern_class!(
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
|
|
@ -12,3 +15,121 @@ extern_class!(
|
|||
type Super = NSResponder;
|
||||
}
|
||||
);
|
||||
|
||||
pub(crate) fn NSApp() -> Id<NSApplication, Shared> {
|
||||
// TODO: Only allow access from main thread
|
||||
NSApplication::shared(unsafe { MainThreadMarker::new_unchecked() })
|
||||
}
|
||||
|
||||
extern_methods!(
|
||||
unsafe impl NSApplication {
|
||||
/// This can only be called on the main thread since it may initialize
|
||||
/// the application and since it's parameters may be changed by the main
|
||||
/// thread at any time (hence it is only safe to access on the main thread).
|
||||
pub fn shared(_mtm: MainThreadMarker) -> Id<Self, Shared> {
|
||||
let app: Option<_> = unsafe { msg_send_id![Self::class(), sharedApplication] };
|
||||
// SAFETY: `sharedApplication` always initializes the app if it isn't already
|
||||
unsafe { app.unwrap_unchecked() }
|
||||
}
|
||||
|
||||
pub fn currentEvent(&self) -> Option<Id<NSEvent, Shared>> {
|
||||
unsafe { msg_send_id![self, currentEvent] }
|
||||
}
|
||||
|
||||
#[sel(postEvent:atStart:)]
|
||||
pub fn postEvent_atStart(&self, event: &NSEvent, front_of_queue: bool);
|
||||
|
||||
#[sel(presentationOptions)]
|
||||
pub fn presentationOptions(&self) -> NSApplicationPresentationOptions;
|
||||
|
||||
pub fn windows(&self) -> Id<NSArray<NSWindow, Shared>, Shared> {
|
||||
unsafe { msg_send_id![self, windows] }
|
||||
}
|
||||
|
||||
pub fn keyWindow(&self) -> Option<Id<NSWindow, Shared>> {
|
||||
unsafe { msg_send_id![self, keyWindow] }
|
||||
}
|
||||
|
||||
// TODO: NSApplicationDelegate
|
||||
#[sel(setDelegate:)]
|
||||
pub fn setDelegate(&self, delegate: &Object);
|
||||
|
||||
#[sel(setPresentationOptions:)]
|
||||
pub fn setPresentationOptions(&self, options: NSApplicationPresentationOptions);
|
||||
|
||||
#[sel(hide:)]
|
||||
pub fn hide(&self, sender: Option<&Object>);
|
||||
|
||||
#[sel(orderFrontCharacterPalette:)]
|
||||
#[allow(dead_code)]
|
||||
pub fn orderFrontCharacterPalette(&self, sender: Option<&Object>);
|
||||
|
||||
#[sel(hideOtherApplications:)]
|
||||
pub fn hideOtherApplications(&self, sender: Option<&Object>);
|
||||
|
||||
#[sel(stop:)]
|
||||
pub fn stop(&self, sender: Option<&Object>);
|
||||
|
||||
#[sel(activateIgnoringOtherApps:)]
|
||||
pub fn activateIgnoringOtherApps(&self, ignore: bool);
|
||||
|
||||
#[sel(requestUserAttention:)]
|
||||
pub fn requestUserAttention(&self, type_: NSRequestUserAttentionType) -> NSInteger;
|
||||
|
||||
#[sel(setActivationPolicy:)]
|
||||
pub fn setActivationPolicy(&self, policy: NSApplicationActivationPolicy) -> bool;
|
||||
|
||||
#[sel(setMainMenu:)]
|
||||
pub fn setMainMenu(&self, menu: &NSMenu);
|
||||
|
||||
#[sel(run)]
|
||||
pub unsafe fn run(&self);
|
||||
}
|
||||
);
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(isize)] // NSInteger
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum NSApplicationActivationPolicy {
|
||||
NSApplicationActivationPolicyRegular = 0,
|
||||
NSApplicationActivationPolicyAccessory = 1,
|
||||
NSApplicationActivationPolicyProhibited = 2,
|
||||
NSApplicationActivationPolicyERROR = -1,
|
||||
}
|
||||
|
||||
unsafe impl Encode for NSApplicationActivationPolicy {
|
||||
const ENCODING: Encoding = NSInteger::ENCODING;
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub struct NSApplicationPresentationOptions: NSUInteger {
|
||||
const NSApplicationPresentationDefault = 0;
|
||||
const NSApplicationPresentationAutoHideDock = 1 << 0;
|
||||
const NSApplicationPresentationHideDock = 1 << 1;
|
||||
const NSApplicationPresentationAutoHideMenuBar = 1 << 2;
|
||||
const NSApplicationPresentationHideMenuBar = 1 << 3;
|
||||
const NSApplicationPresentationDisableAppleMenu = 1 << 4;
|
||||
const NSApplicationPresentationDisableProcessSwitching = 1 << 5;
|
||||
const NSApplicationPresentationDisableForceQuit = 1 << 6;
|
||||
const NSApplicationPresentationDisableSessionTermination = 1 << 7;
|
||||
const NSApplicationPresentationDisableHideApplication = 1 << 8;
|
||||
const NSApplicationPresentationDisableMenuBarTransparency = 1 << 9;
|
||||
const NSApplicationPresentationFullScreen = 1 << 10;
|
||||
const NSApplicationPresentationAutoHideToolbar = 1 << 11;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Encode for NSApplicationPresentationOptions {
|
||||
const ENCODING: Encoding = NSUInteger::ENCODING;
|
||||
}
|
||||
|
||||
#[repr(usize)] // NSUInteger
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum NSRequestUserAttentionType {
|
||||
NSCriticalRequest = 0,
|
||||
NSInformationalRequest = 10,
|
||||
}
|
||||
|
||||
unsafe impl Encode for NSRequestUserAttentionType {
|
||||
const ENCODING: Encoding = NSUInteger::ENCODING;
|
||||
}
|
||||
|
|
|
|||
14
src/platform_impl/macos/appkit/button.rs
Normal file
14
src/platform_impl/macos/appkit/button.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
use objc2::foundation::NSObject;
|
||||
use objc2::{extern_class, ClassType};
|
||||
|
||||
use super::{NSControl, NSResponder, NSView};
|
||||
|
||||
extern_class!(
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct NSButton;
|
||||
|
||||
unsafe impl ClassType for NSButton {
|
||||
#[inherits(NSView, NSResponder, NSObject)]
|
||||
type Super = NSControl;
|
||||
}
|
||||
);
|
||||
28
src/platform_impl/macos/appkit/color.rs
Normal file
28
src/platform_impl/macos/appkit/color.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
use objc2::foundation::NSObject;
|
||||
use objc2::rc::{Id, Shared};
|
||||
use objc2::{extern_class, extern_methods, msg_send_id, ClassType};
|
||||
|
||||
extern_class!(
|
||||
/// An object that stores color data and sometimes opacity (alpha value).
|
||||
///
|
||||
/// <https://developer.apple.com/documentation/appkit/nscolor?language=objc>
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct NSColor;
|
||||
|
||||
unsafe impl ClassType for NSColor {
|
||||
type Super = NSObject;
|
||||
}
|
||||
);
|
||||
|
||||
// SAFETY: Documentation clearly states:
|
||||
// > Color objects are immutable and thread-safe
|
||||
unsafe impl Send for NSColor {}
|
||||
unsafe impl Sync for NSColor {}
|
||||
|
||||
extern_methods!(
|
||||
unsafe impl NSColor {
|
||||
pub fn clear() -> Id<Self, Shared> {
|
||||
unsafe { msg_send_id![Self::class(), clearColor] }
|
||||
}
|
||||
}
|
||||
);
|
||||
14
src/platform_impl/macos/appkit/control.rs
Normal file
14
src/platform_impl/macos/appkit/control.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
use objc2::foundation::NSObject;
|
||||
use objc2::{extern_class, ClassType};
|
||||
|
||||
use super::{NSResponder, NSView};
|
||||
|
||||
extern_class!(
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct NSControl;
|
||||
|
||||
unsafe impl ClassType for NSControl {
|
||||
#[inherits(NSResponder, NSObject)]
|
||||
type Super = NSView;
|
||||
}
|
||||
);
|
||||
|
|
@ -3,7 +3,7 @@ use once_cell::sync::Lazy;
|
|||
use objc2::foundation::{NSData, NSDictionary, NSNumber, NSObject, NSPoint, NSString};
|
||||
use objc2::rc::{DefaultId, Id, Shared};
|
||||
use objc2::runtime::Sel;
|
||||
use objc2::{extern_class, extern_methods, msg_send_id, ns_string, ClassType};
|
||||
use objc2::{extern_class, extern_methods, msg_send_id, ns_string, sel, ClassType};
|
||||
|
||||
use super::NSImage;
|
||||
use crate::window::CursorIcon;
|
||||
|
|
|
|||
234
src/platform_impl/macos/appkit/event.rs
Normal file
234
src/platform_impl/macos/appkit/event.rs
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
use std::os::raw::c_ushort;
|
||||
|
||||
use objc2::encode::{Encode, Encoding};
|
||||
use objc2::foundation::{
|
||||
CGFloat, NSCopying, NSInteger, NSObject, NSPoint, NSString, NSTimeInterval, NSUInteger,
|
||||
};
|
||||
use objc2::rc::{Id, Shared};
|
||||
use objc2::{extern_class, extern_methods, msg_send_id, ClassType};
|
||||
|
||||
extern_class!(
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct NSEvent;
|
||||
|
||||
unsafe impl ClassType for NSEvent {
|
||||
type Super = NSObject;
|
||||
}
|
||||
);
|
||||
|
||||
// > Safely handled only on the same thread, whether that be the main thread
|
||||
// > or a secondary thread; otherwise you run the risk of having events get
|
||||
// > out of sequence.
|
||||
// <https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CocoaFundamentals/AddingBehaviortoaCocoaProgram/AddingBehaviorCocoa.html#//apple_ref/doc/uid/TP40002974-CH5-SW47>
|
||||
// <https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html#//apple_ref/doc/uid/10000057i-CH12-123383>
|
||||
|
||||
extern_methods!(
|
||||
unsafe impl NSEvent {
|
||||
unsafe fn otherEventWithType(
|
||||
type_: NSEventType,
|
||||
location: NSPoint,
|
||||
flags: NSEventModifierFlags,
|
||||
time: NSTimeInterval,
|
||||
window_num: NSInteger,
|
||||
context: Option<&NSObject>, // NSGraphicsContext
|
||||
subtype: NSEventSubtype,
|
||||
data1: NSInteger,
|
||||
data2: NSInteger,
|
||||
) -> Id<Self, Shared> {
|
||||
unsafe {
|
||||
msg_send_id![
|
||||
Self::class(),
|
||||
otherEventWithType: type_,
|
||||
location: location,
|
||||
modifierFlags: flags,
|
||||
timestamp: time,
|
||||
windowNumber: window_num,
|
||||
context: context,
|
||||
subtype: subtype,
|
||||
data1: data1,
|
||||
data2: data2,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dummy() -> Id<Self, Shared> {
|
||||
unsafe {
|
||||
Self::otherEventWithType(
|
||||
NSEventType::NSApplicationDefined,
|
||||
NSPoint::new(0.0, 0.0),
|
||||
NSEventModifierFlags::empty(),
|
||||
0.0,
|
||||
0,
|
||||
None,
|
||||
NSEventSubtype::NSWindowExposedEventType,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[sel(locationInWindow)]
|
||||
pub fn locationInWindow(&self) -> NSPoint;
|
||||
|
||||
// TODO: MainThreadMarker
|
||||
#[sel(pressedMouseButtons)]
|
||||
pub fn pressedMouseButtons() -> NSUInteger;
|
||||
|
||||
#[sel(modifierFlags)]
|
||||
pub fn modifierFlags(&self) -> NSEventModifierFlags;
|
||||
|
||||
#[sel(type)]
|
||||
pub fn type_(&self) -> NSEventType;
|
||||
|
||||
// In AppKit, `keyCode` refers to the position (scancode) of a key rather than its character,
|
||||
// and there is no easy way to navtively retrieve the layout-dependent character.
|
||||
// In winit, we use keycode to refer to the key's character, and so this function aligns
|
||||
// AppKit's terminology with ours.
|
||||
#[sel(keyCode)]
|
||||
pub fn scancode(&self) -> c_ushort;
|
||||
|
||||
#[sel(magnification)]
|
||||
pub fn magnification(&self) -> CGFloat;
|
||||
|
||||
#[sel(phase)]
|
||||
pub fn phase(&self) -> NSEventPhase;
|
||||
|
||||
#[sel(momentumPhase)]
|
||||
pub fn momentumPhase(&self) -> NSEventPhase;
|
||||
|
||||
#[sel(deltaX)]
|
||||
pub fn deltaX(&self) -> CGFloat;
|
||||
|
||||
#[sel(deltaY)]
|
||||
pub fn deltaY(&self) -> CGFloat;
|
||||
|
||||
#[sel(buttonNumber)]
|
||||
pub fn buttonNumber(&self) -> NSInteger;
|
||||
|
||||
#[sel(scrollingDeltaX)]
|
||||
pub fn scrollingDeltaX(&self) -> CGFloat;
|
||||
|
||||
#[sel(scrollingDeltaY)]
|
||||
pub fn scrollingDeltaY(&self) -> CGFloat;
|
||||
|
||||
#[sel(hasPreciseScrollingDeltas)]
|
||||
pub fn hasPreciseScrollingDeltas(&self) -> bool;
|
||||
|
||||
#[sel(rotation)]
|
||||
pub fn rotation(&self) -> f32;
|
||||
|
||||
#[sel(pressure)]
|
||||
pub fn pressure(&self) -> f32;
|
||||
|
||||
#[sel(stage)]
|
||||
pub fn stage(&self) -> NSInteger;
|
||||
|
||||
pub fn characters(&self) -> Option<Id<NSString, Shared>> {
|
||||
unsafe { msg_send_id![self, characters] }
|
||||
}
|
||||
|
||||
pub fn charactersIgnoringModifiers(&self) -> Option<Id<NSString, Shared>> {
|
||||
unsafe { msg_send_id![self, charactersIgnoringModifiers] }
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
unsafe impl NSCopying for NSEvent {
|
||||
type Ownership = Shared;
|
||||
type Output = NSEvent;
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub struct NSEventModifierFlags: NSUInteger {
|
||||
const NSAlphaShiftKeyMask = 1 << 16;
|
||||
const NSShiftKeyMask = 1 << 17;
|
||||
const NSControlKeyMask = 1 << 18;
|
||||
const NSAlternateKeyMask = 1 << 19;
|
||||
const NSCommandKeyMask = 1 << 20;
|
||||
const NSNumericPadKeyMask = 1 << 21;
|
||||
const NSHelpKeyMask = 1 << 22;
|
||||
const NSFunctionKeyMask = 1 << 23;
|
||||
const NSDeviceIndependentModifierFlagsMask = 0xffff0000;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Encode for NSEventModifierFlags {
|
||||
const ENCODING: Encoding = NSUInteger::ENCODING;
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub struct NSEventPhase: NSUInteger {
|
||||
const NSEventPhaseNone = 0;
|
||||
const NSEventPhaseBegan = 0x1 << 0;
|
||||
const NSEventPhaseStationary = 0x1 << 1;
|
||||
const NSEventPhaseChanged = 0x1 << 2;
|
||||
const NSEventPhaseEnded = 0x1 << 3;
|
||||
const NSEventPhaseCancelled = 0x1 << 4;
|
||||
const NSEventPhaseMayBegin = 0x1 << 5;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Encode for NSEventPhase {
|
||||
const ENCODING: Encoding = NSUInteger::ENCODING;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(i16)] // short
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum NSEventSubtype {
|
||||
// TODO: Not sure what these values are
|
||||
// NSMouseEventSubtype = NX_SUBTYPE_DEFAULT,
|
||||
// NSTabletPointEventSubtype = NX_SUBTYPE_TABLET_POINT,
|
||||
// NSTabletProximityEventSubtype = NX_SUBTYPE_TABLET_PROXIMITY
|
||||
// NSTouchEventSubtype = NX_SUBTYPE_MOUSE_TOUCH,
|
||||
NSWindowExposedEventType = 0,
|
||||
NSApplicationActivatedEventType = 1,
|
||||
NSApplicationDeactivatedEventType = 2,
|
||||
NSWindowMovedEventType = 4,
|
||||
NSScreenChangedEventType = 8,
|
||||
NSAWTEventType = 16,
|
||||
}
|
||||
|
||||
unsafe impl Encode for NSEventSubtype {
|
||||
const ENCODING: Encoding = i16::ENCODING;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[repr(usize)] // NSUInteger
|
||||
pub enum NSEventType {
|
||||
NSLeftMouseDown = 1,
|
||||
NSLeftMouseUp = 2,
|
||||
NSRightMouseDown = 3,
|
||||
NSRightMouseUp = 4,
|
||||
NSMouseMoved = 5,
|
||||
NSLeftMouseDragged = 6,
|
||||
NSRightMouseDragged = 7,
|
||||
NSMouseEntered = 8,
|
||||
NSMouseExited = 9,
|
||||
NSKeyDown = 10,
|
||||
NSKeyUp = 11,
|
||||
NSFlagsChanged = 12,
|
||||
NSAppKitDefined = 13,
|
||||
NSSystemDefined = 14,
|
||||
NSApplicationDefined = 15,
|
||||
NSPeriodic = 16,
|
||||
NSCursorUpdate = 17,
|
||||
NSScrollWheel = 22,
|
||||
NSTabletPoint = 23,
|
||||
NSTabletProximity = 24,
|
||||
NSOtherMouseDown = 25,
|
||||
NSOtherMouseUp = 26,
|
||||
NSOtherMouseDragged = 27,
|
||||
NSEventTypeGesture = 29,
|
||||
NSEventTypeMagnify = 30,
|
||||
NSEventTypeSwipe = 31,
|
||||
NSEventTypeRotate = 18,
|
||||
NSEventTypeBeginGesture = 19,
|
||||
NSEventTypeEndGesture = 20,
|
||||
NSEventTypePressure = 34,
|
||||
}
|
||||
|
||||
unsafe impl Encode for NSEventType {
|
||||
const ENCODING: Encoding = NSUInteger::ENCODING;
|
||||
}
|
||||
25
src/platform_impl/macos/appkit/menu.rs
Normal file
25
src/platform_impl/macos/appkit/menu.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
use objc2::foundation::NSObject;
|
||||
use objc2::rc::{Id, Shared};
|
||||
use objc2::{extern_class, extern_methods, msg_send_id, ClassType};
|
||||
|
||||
use super::NSMenuItem;
|
||||
|
||||
extern_class!(
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct NSMenu;
|
||||
|
||||
unsafe impl ClassType for NSMenu {
|
||||
type Super = NSObject;
|
||||
}
|
||||
);
|
||||
|
||||
extern_methods!(
|
||||
unsafe impl NSMenu {
|
||||
pub fn new() -> Id<Self, Shared> {
|
||||
unsafe { msg_send_id![Self::class(), new] }
|
||||
}
|
||||
|
||||
#[sel(addItem:)]
|
||||
pub fn addItem(&self, item: &NSMenuItem);
|
||||
}
|
||||
);
|
||||
48
src/platform_impl/macos/appkit/menu_item.rs
Normal file
48
src/platform_impl/macos/appkit/menu_item.rs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
use objc2::foundation::{NSObject, NSString};
|
||||
use objc2::rc::{Id, Shared};
|
||||
use objc2::runtime::Sel;
|
||||
use objc2::{extern_class, extern_methods, msg_send_id, ClassType};
|
||||
|
||||
use super::{NSEventModifierFlags, NSMenu};
|
||||
|
||||
extern_class!(
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct NSMenuItem;
|
||||
|
||||
unsafe impl ClassType for NSMenuItem {
|
||||
type Super = NSObject;
|
||||
}
|
||||
);
|
||||
|
||||
extern_methods!(
|
||||
unsafe impl NSMenuItem {
|
||||
pub fn new() -> Id<Self, Shared> {
|
||||
unsafe { msg_send_id![Self::class(), new] }
|
||||
}
|
||||
|
||||
pub fn newWithTitle(
|
||||
title: &NSString,
|
||||
action: Sel,
|
||||
key_equivalent: &NSString,
|
||||
) -> Id<Self, Shared> {
|
||||
unsafe {
|
||||
msg_send_id![
|
||||
msg_send_id![Self::class(), alloc],
|
||||
initWithTitle: title,
|
||||
action: action,
|
||||
keyEquivalent: key_equivalent,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn separatorItem() -> Id<Self, Shared> {
|
||||
unsafe { msg_send_id![Self::class(), separatorItem] }
|
||||
}
|
||||
|
||||
#[sel(setKeyEquivalentModifierMask:)]
|
||||
pub fn setKeyEquivalentModifierMask(&self, mask: NSEventModifierFlags);
|
||||
|
||||
#[sel(setSubmenu:)]
|
||||
pub fn setSubmenu(&self, submenu: &NSMenu);
|
||||
}
|
||||
);
|
||||
|
|
@ -1,18 +1,59 @@
|
|||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
//! Safe bindings for the AppKit framework.
|
||||
//!
|
||||
//! These are split out from the rest of `winit` to make safety easier to review.
|
||||
//! In the future, these should probably live in another crate like `cacao`.
|
||||
//!
|
||||
//! TODO: Main thread safety.
|
||||
// Objective-C methods have different conventions, and it's much easier to
|
||||
// understand if we just use the same names
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(clippy::too_many_arguments)]
|
||||
#![allow(clippy::enum_variant_names)]
|
||||
#![allow(non_upper_case_globals)]
|
||||
|
||||
mod application;
|
||||
mod button;
|
||||
mod color;
|
||||
mod control;
|
||||
mod cursor;
|
||||
mod event;
|
||||
mod image;
|
||||
mod menu;
|
||||
mod menu_item;
|
||||
mod pasteboard;
|
||||
mod responder;
|
||||
mod screen;
|
||||
mod text_input_context;
|
||||
mod version;
|
||||
mod view;
|
||||
mod window;
|
||||
|
||||
pub(crate) use self::application::NSApplication;
|
||||
pub(crate) use self::application::{
|
||||
NSApp, NSApplication, NSApplicationActivationPolicy, NSApplicationPresentationOptions,
|
||||
NSRequestUserAttentionType,
|
||||
};
|
||||
pub(crate) use self::button::NSButton;
|
||||
pub(crate) use self::color::NSColor;
|
||||
pub(crate) use self::control::NSControl;
|
||||
pub(crate) use self::cursor::NSCursor;
|
||||
#[allow(unused_imports)]
|
||||
pub(crate) use self::event::{
|
||||
NSEvent, NSEventModifierFlags, NSEventPhase, NSEventSubtype, NSEventType,
|
||||
};
|
||||
pub(crate) use self::image::NSImage;
|
||||
pub(crate) use self::menu::NSMenu;
|
||||
pub(crate) use self::menu_item::NSMenuItem;
|
||||
pub(crate) use self::pasteboard::{NSFilenamesPboardType, NSPasteboard, NSPasteboardType};
|
||||
pub(crate) use self::responder::NSResponder;
|
||||
pub(crate) use self::view::NSView;
|
||||
pub(crate) use self::window::NSWindow;
|
||||
#[allow(unused_imports)]
|
||||
pub(crate) use self::screen::{NSDeviceDescriptionKey, NSScreen};
|
||||
pub(crate) use self::text_input_context::NSTextInputContext;
|
||||
pub(crate) use self::version::NSAppKitVersion;
|
||||
pub(crate) use self::view::{NSTrackingRectTag, NSView};
|
||||
pub(crate) use self::window::{
|
||||
NSBackingStoreType, NSWindow, NSWindowButton, NSWindowLevel, NSWindowOcclusionState,
|
||||
NSWindowStyleMask, NSWindowTitleVisibility,
|
||||
};
|
||||
|
||||
#[link(name = "AppKit", kind = "framework")]
|
||||
extern "C" {}
|
||||
|
|
|
|||
26
src/platform_impl/macos/appkit/pasteboard.rs
Normal file
26
src/platform_impl/macos/appkit/pasteboard.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
use objc2::foundation::{NSObject, NSString};
|
||||
use objc2::rc::{Id, Shared};
|
||||
use objc2::{extern_class, extern_methods, msg_send_id, ClassType};
|
||||
|
||||
extern_class!(
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct NSPasteboard;
|
||||
|
||||
unsafe impl ClassType for NSPasteboard {
|
||||
type Super = NSObject;
|
||||
}
|
||||
);
|
||||
|
||||
extern_methods!(
|
||||
unsafe impl NSPasteboard {
|
||||
pub fn propertyListForType(&self, type_: &NSPasteboardType) -> Id<NSObject, Shared> {
|
||||
unsafe { msg_send_id![self, propertyListForType: type_] }
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
pub type NSPasteboardType = NSString;
|
||||
|
||||
extern "C" {
|
||||
pub static NSFilenamesPboardType: &'static NSPasteboardType;
|
||||
}
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
use objc2::foundation::NSObject;
|
||||
use objc2::{extern_class, ClassType};
|
||||
use objc2::foundation::{NSArray, NSObject};
|
||||
use objc2::rc::Shared;
|
||||
use objc2::{extern_class, extern_methods, ClassType};
|
||||
|
||||
use super::NSEvent;
|
||||
|
||||
extern_class!(
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
|
|
@ -9,3 +12,13 @@ extern_class!(
|
|||
type Super = NSObject;
|
||||
}
|
||||
);
|
||||
|
||||
// Documented as "Thread-Unsafe".
|
||||
|
||||
extern_methods!(
|
||||
unsafe impl NSResponder {
|
||||
// TODO: Allow "immutably" on main thread
|
||||
#[sel(interpretKeyEvents:)]
|
||||
pub unsafe fn interpretKeyEvents(&mut self, events: &NSArray<NSEvent, Shared>);
|
||||
}
|
||||
);
|
||||
|
|
|
|||
64
src/platform_impl/macos/appkit/screen.rs
Normal file
64
src/platform_impl/macos/appkit/screen.rs
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
use objc2::foundation::{CGFloat, NSArray, NSDictionary, NSNumber, NSObject, NSRect, NSString};
|
||||
use objc2::rc::{Id, Shared};
|
||||
use objc2::runtime::Object;
|
||||
use objc2::{extern_class, extern_methods, msg_send_id, ns_string, ClassType};
|
||||
|
||||
extern_class!(
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct NSScreen;
|
||||
|
||||
unsafe impl ClassType for NSScreen {
|
||||
type Super = NSObject;
|
||||
}
|
||||
);
|
||||
|
||||
// TODO: Main thread marker!
|
||||
|
||||
extern_methods!(
|
||||
unsafe impl NSScreen {
|
||||
/// The application object must have been created.
|
||||
pub fn main() -> Option<Id<Self, Shared>> {
|
||||
unsafe { msg_send_id![Self::class(), mainScreen] }
|
||||
}
|
||||
|
||||
/// The application object must have been created.
|
||||
pub fn screens() -> Id<NSArray<Self, Shared>, Shared> {
|
||||
unsafe { msg_send_id![Self::class(), screens] }
|
||||
}
|
||||
|
||||
#[sel(frame)]
|
||||
pub fn frame(&self) -> NSRect;
|
||||
|
||||
#[sel(visibleFrame)]
|
||||
pub fn visibleFrame(&self) -> NSRect;
|
||||
|
||||
pub fn deviceDescription(
|
||||
&self,
|
||||
) -> Id<NSDictionary<NSDeviceDescriptionKey, Object>, Shared> {
|
||||
unsafe { msg_send_id![self, deviceDescription] }
|
||||
}
|
||||
|
||||
pub fn display_id(&self) -> u32 {
|
||||
let device_description = self.deviceDescription();
|
||||
|
||||
// Retrieve the CGDirectDisplayID associated with this screen
|
||||
//
|
||||
// SAFETY: The value from @"NSScreenNumber" in deviceDescription is guaranteed
|
||||
// to be an NSNumber. See documentation for `deviceDescription` for details:
|
||||
// <https://developer.apple.com/documentation/appkit/nsscreen/1388360-devicedescription?language=objc>
|
||||
let obj = device_description
|
||||
.get(ns_string!("NSScreenNumber"))
|
||||
.expect("failed getting screen display id from device description");
|
||||
let obj: *const Object = obj;
|
||||
let obj: *const NSNumber = obj.cast();
|
||||
let obj: &NSNumber = unsafe { &*obj };
|
||||
|
||||
obj.as_u32()
|
||||
}
|
||||
|
||||
#[sel(backingScaleFactor)]
|
||||
pub fn backingScaleFactor(&self) -> CGFloat;
|
||||
}
|
||||
);
|
||||
|
||||
pub type NSDeviceDescriptionKey = NSString;
|
||||
31
src/platform_impl/macos/appkit/text_input_context.rs
Normal file
31
src/platform_impl/macos/appkit/text_input_context.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
use objc2::foundation::{NSObject, NSString};
|
||||
use objc2::rc::{Id, Shared};
|
||||
use objc2::{extern_class, extern_methods, msg_send_id, ClassType};
|
||||
|
||||
type NSTextInputSourceIdentifier = NSString;
|
||||
|
||||
extern_class!(
|
||||
/// Main-Thread-Only!
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct NSTextInputContext;
|
||||
|
||||
unsafe impl ClassType for NSTextInputContext {
|
||||
type Super = NSObject;
|
||||
}
|
||||
);
|
||||
|
||||
extern_methods!(
|
||||
unsafe impl NSTextInputContext {
|
||||
#[sel(invalidateCharacterCoordinates)]
|
||||
pub fn invalidateCharacterCoordinates(&self);
|
||||
|
||||
#[sel(discardMarkedText)]
|
||||
pub fn discardMarkedText(&self);
|
||||
|
||||
pub fn selectedKeyboardInputSource(
|
||||
&self,
|
||||
) -> Option<Id<NSTextInputSourceIdentifier, Shared>> {
|
||||
unsafe { msg_send_id![self, selectedKeyboardInputSource] }
|
||||
}
|
||||
}
|
||||
);
|
||||
62
src/platform_impl/macos/appkit/version.rs
Normal file
62
src/platform_impl/macos/appkit/version.rs
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#[repr(transparent)]
|
||||
#[derive(PartialEq, PartialOrd, Debug, Clone, Copy)]
|
||||
pub struct NSAppKitVersion(f64);
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[allow(non_upper_case_globals)]
|
||||
impl NSAppKitVersion {
|
||||
pub fn current() -> Self {
|
||||
extern "C" {
|
||||
static NSAppKitVersionNumber: NSAppKitVersion;
|
||||
}
|
||||
|
||||
unsafe { NSAppKitVersionNumber }
|
||||
}
|
||||
|
||||
pub fn floor(self) -> Self {
|
||||
Self(self.0.floor())
|
||||
}
|
||||
|
||||
pub const NSAppKitVersionNumber10_0: Self = Self(577.0);
|
||||
pub const NSAppKitVersionNumber10_1: Self = Self(620.0);
|
||||
pub const NSAppKitVersionNumber10_2: Self = Self(663.0);
|
||||
pub const NSAppKitVersionNumber10_2_3: Self = Self(663.6);
|
||||
pub const NSAppKitVersionNumber10_3: Self = Self(743.0);
|
||||
pub const NSAppKitVersionNumber10_3_2: Self = Self(743.14);
|
||||
pub const NSAppKitVersionNumber10_3_3: Self = Self(743.2);
|
||||
pub const NSAppKitVersionNumber10_3_5: Self = Self(743.24);
|
||||
pub const NSAppKitVersionNumber10_3_7: Self = Self(743.33);
|
||||
pub const NSAppKitVersionNumber10_3_9: Self = Self(743.36);
|
||||
pub const NSAppKitVersionNumber10_4: Self = Self(824.0);
|
||||
pub const NSAppKitVersionNumber10_4_1: Self = Self(824.1);
|
||||
pub const NSAppKitVersionNumber10_4_3: Self = Self(824.23);
|
||||
pub const NSAppKitVersionNumber10_4_4: Self = Self(824.33);
|
||||
pub const NSAppKitVersionNumber10_4_7: Self = Self(824.41);
|
||||
pub const NSAppKitVersionNumber10_5: Self = Self(949.0);
|
||||
pub const NSAppKitVersionNumber10_5_2: Self = Self(949.27);
|
||||
pub const NSAppKitVersionNumber10_5_3: Self = Self(949.33);
|
||||
pub const NSAppKitVersionNumber10_6: Self = Self(1038.0);
|
||||
pub const NSAppKitVersionNumber10_7: Self = Self(1138.0);
|
||||
pub const NSAppKitVersionNumber10_7_2: Self = Self(1138.23);
|
||||
pub const NSAppKitVersionNumber10_7_3: Self = Self(1138.32);
|
||||
pub const NSAppKitVersionNumber10_7_4: Self = Self(1138.47);
|
||||
pub const NSAppKitVersionNumber10_8: Self = Self(1187.0);
|
||||
pub const NSAppKitVersionNumber10_9: Self = Self(1265.0);
|
||||
pub const NSAppKitVersionNumber10_10: Self = Self(1343.0);
|
||||
pub const NSAppKitVersionNumber10_10_2: Self = Self(1344.0);
|
||||
pub const NSAppKitVersionNumber10_10_3: Self = Self(1347.0);
|
||||
pub const NSAppKitVersionNumber10_10_4: Self = Self(1348.0);
|
||||
pub const NSAppKitVersionNumber10_10_5: Self = Self(1348.0);
|
||||
pub const NSAppKitVersionNumber10_10_Max: Self = Self(1349.0);
|
||||
pub const NSAppKitVersionNumber10_11: Self = Self(1404.0);
|
||||
pub const NSAppKitVersionNumber10_11_1: Self = Self(1404.13);
|
||||
pub const NSAppKitVersionNumber10_11_2: Self = Self(1404.34);
|
||||
pub const NSAppKitVersionNumber10_11_3: Self = Self(1404.34);
|
||||
pub const NSAppKitVersionNumber10_12: Self = Self(1504.0);
|
||||
pub const NSAppKitVersionNumber10_12_1: Self = Self(1504.60);
|
||||
pub const NSAppKitVersionNumber10_12_2: Self = Self(1504.76);
|
||||
pub const NSAppKitVersionNumber10_13: Self = Self(1561.0);
|
||||
pub const NSAppKitVersionNumber10_13_1: Self = Self(1561.1);
|
||||
pub const NSAppKitVersionNumber10_13_2: Self = Self(1561.2);
|
||||
pub const NSAppKitVersionNumber10_13_4: Self = Self(1561.4);
|
||||
}
|
||||
|
|
@ -1,7 +1,13 @@
|
|||
use objc2::foundation::{NSObject, NSRect};
|
||||
use objc2::{extern_class, extern_methods, ClassType};
|
||||
use std::ffi::c_void;
|
||||
use std::num::NonZeroIsize;
|
||||
use std::ptr;
|
||||
|
||||
use super::{NSCursor, NSResponder};
|
||||
use objc2::foundation::{NSObject, NSPoint, NSRect};
|
||||
use objc2::rc::{Id, Shared};
|
||||
use objc2::runtime::Object;
|
||||
use objc2::{extern_class, extern_methods, msg_send_id, ClassType};
|
||||
|
||||
use super::{NSCursor, NSResponder, NSTextInputContext};
|
||||
|
||||
extern_class!(
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
|
|
@ -13,16 +19,77 @@ extern_class!(
|
|||
}
|
||||
);
|
||||
|
||||
// Documented as "Main Thread Only".
|
||||
// > generally thread safe, although operations on views such as creating,
|
||||
// > resizing, and moving should happen on the main thread.
|
||||
// <https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CocoaFundamentals/AddingBehaviortoaCocoaProgram/AddingBehaviorCocoa.html#//apple_ref/doc/uid/TP40002974-CH5-SW47>
|
||||
//
|
||||
// > If you want to use a thread to draw to a view, bracket all drawing code
|
||||
// > between the lockFocusIfCanDraw and unlockFocus methods of NSView.
|
||||
// <https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html#//apple_ref/doc/uid/10000057i-CH12-123351-BBCFIIEB>
|
||||
|
||||
extern_methods!(
|
||||
/// Getter methods
|
||||
unsafe impl NSView {
|
||||
#[sel(frame)]
|
||||
pub fn frame(&self) -> NSRect;
|
||||
|
||||
#[sel(bounds)]
|
||||
pub fn bounds(&self) -> NSRect;
|
||||
|
||||
pub fn inputContext(
|
||||
&self,
|
||||
// _mtm: MainThreadMarker,
|
||||
) -> Option<Id<NSTextInputContext, Shared>> {
|
||||
unsafe { msg_send_id![self, inputContext] }
|
||||
}
|
||||
|
||||
#[sel(visibleRect)]
|
||||
pub fn visibleRect(&self) -> NSRect;
|
||||
|
||||
#[sel(hasMarkedText)]
|
||||
pub fn hasMarkedText(&self) -> bool;
|
||||
|
||||
#[sel(convertPoint:fromView:)]
|
||||
pub fn convertPoint_fromView(&self, point: NSPoint, view: Option<&NSView>) -> NSPoint;
|
||||
}
|
||||
|
||||
unsafe impl NSView {
|
||||
#[sel(setWantsBestResolutionOpenGLSurface:)]
|
||||
pub fn setWantsBestResolutionOpenGLSurface(&self, value: bool);
|
||||
|
||||
#[sel(setWantsLayer:)]
|
||||
pub fn setWantsLayer(&self, wants_layer: bool);
|
||||
|
||||
#[sel(setPostsFrameChangedNotifications:)]
|
||||
pub fn setPostsFrameChangedNotifications(&mut self, value: bool);
|
||||
|
||||
#[sel(removeTrackingRect:)]
|
||||
pub fn removeTrackingRect(&self, tag: NSTrackingRectTag);
|
||||
|
||||
#[sel(addTrackingRect:owner:userData:assumeInside:)]
|
||||
unsafe fn inner_addTrackingRect(
|
||||
&self,
|
||||
rect: NSRect,
|
||||
owner: &Object,
|
||||
user_data: *mut c_void,
|
||||
assume_inside: bool,
|
||||
) -> Option<NSTrackingRectTag>;
|
||||
|
||||
pub fn add_tracking_rect(&self, rect: NSRect, assume_inside: bool) -> NSTrackingRectTag {
|
||||
// SAFETY: The user data is NULL, so it is valid
|
||||
unsafe { self.inner_addTrackingRect(rect, self, ptr::null_mut(), assume_inside) }
|
||||
.expect("failed creating tracking rect")
|
||||
}
|
||||
|
||||
#[sel(addCursorRect:cursor:)]
|
||||
// NSCursor safe to take by shared reference since it is already immutable
|
||||
pub fn addCursorRect(&self, rect: NSRect, cursor: &NSCursor);
|
||||
|
||||
#[sel(setHidden:)]
|
||||
pub fn setHidden(&self, hidden: bool);
|
||||
}
|
||||
);
|
||||
|
||||
/// <https://developer.apple.com/documentation/appkit/nstrackingrecttag?language=objc>
|
||||
pub type NSTrackingRectTag = NonZeroIsize; // NSInteger, but non-zero!
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
use objc2::foundation::NSObject;
|
||||
use objc2::{extern_class, ClassType};
|
||||
use objc2::encode::{Encode, Encoding};
|
||||
use objc2::foundation::{
|
||||
CGFloat, NSArray, NSInteger, NSObject, NSPoint, NSRect, NSSize, NSString, NSUInteger,
|
||||
};
|
||||
use objc2::rc::{Id, Shared};
|
||||
use objc2::runtime::Object;
|
||||
use objc2::{extern_class, extern_methods, msg_send_id, ClassType};
|
||||
|
||||
use super::NSResponder;
|
||||
use super::{NSButton, NSColor, NSEvent, NSPasteboardType, NSResponder, NSScreen, NSView};
|
||||
|
||||
extern_class!(
|
||||
/// Main-Thread-Only!
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct NSWindow;
|
||||
|
||||
|
|
@ -12,3 +18,314 @@ extern_class!(
|
|||
type Super = NSResponder;
|
||||
}
|
||||
);
|
||||
|
||||
// Documented as "Main Thread Only", but:
|
||||
// > Thread safe in that you can create and manage them on a secondary thread.
|
||||
// <https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CocoaFundamentals/AddingBehaviortoaCocoaProgram/AddingBehaviorCocoa.html#//apple_ref/doc/uid/TP40002974-CH5-SW47>
|
||||
// <https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html#//apple_ref/doc/uid/10000057i-CH12-123364>
|
||||
//
|
||||
// So could in theory be `Send`, and perhaps also `Sync` - but we would like
|
||||
// interior mutability on windows, since that's just much easier, and in that
|
||||
// case, they can't be!
|
||||
|
||||
extern_methods!(
|
||||
unsafe impl NSWindow {
|
||||
#[sel(frame)]
|
||||
pub fn frame(&self) -> NSRect;
|
||||
|
||||
#[sel(backingScaleFactor)]
|
||||
pub fn backingScaleFactor(&self) -> CGFloat;
|
||||
|
||||
pub fn contentView(&self) -> Id<NSView, Shared> {
|
||||
unsafe { msg_send_id![self, contentView] }
|
||||
}
|
||||
|
||||
#[sel(setContentView:)]
|
||||
pub fn setContentView(&self, view: &NSView);
|
||||
|
||||
#[sel(setInitialFirstResponder:)]
|
||||
pub fn setInitialFirstResponder(&self, view: &NSView);
|
||||
|
||||
#[sel(makeFirstResponder:)]
|
||||
#[must_use]
|
||||
pub fn makeFirstResponder(&self, responder: Option<&NSResponder>) -> bool;
|
||||
|
||||
#[sel(contentRectForFrameRect:)]
|
||||
pub fn contentRectForFrameRect(&self, windowFrame: NSRect) -> NSRect;
|
||||
|
||||
pub fn screen(&self) -> Option<Id<NSScreen, Shared>> {
|
||||
unsafe { msg_send_id![self, screen] }
|
||||
}
|
||||
|
||||
#[sel(setContentSize:)]
|
||||
pub fn setContentSize(&self, contentSize: NSSize);
|
||||
|
||||
#[sel(setFrameTopLeftPoint:)]
|
||||
pub fn setFrameTopLeftPoint(&self, point: NSPoint);
|
||||
|
||||
#[sel(setMinSize:)]
|
||||
pub fn setMinSize(&self, minSize: NSSize);
|
||||
|
||||
#[sel(setMaxSize:)]
|
||||
pub fn setMaxSize(&self, maxSize: NSSize);
|
||||
|
||||
#[sel(setResizeIncrements:)]
|
||||
pub fn setResizeIncrements(&self, increments: NSSize);
|
||||
|
||||
#[sel(contentResizeIncrements)]
|
||||
pub fn contentResizeIncrements(&self) -> NSSize;
|
||||
|
||||
#[sel(setContentResizeIncrements:)]
|
||||
pub fn setContentResizeIncrements(&self, increments: NSSize);
|
||||
|
||||
#[sel(setFrame:display:)]
|
||||
pub fn setFrame_display(&self, frameRect: NSRect, flag: bool);
|
||||
|
||||
#[sel(setMovable:)]
|
||||
pub fn setMovable(&self, movable: bool);
|
||||
|
||||
#[sel(setOpaque:)]
|
||||
pub fn setOpaque(&self, opaque: bool);
|
||||
|
||||
#[sel(hasShadow)]
|
||||
pub fn hasShadow(&self) -> bool;
|
||||
|
||||
#[sel(setHasShadow:)]
|
||||
pub fn setHasShadow(&self, has_shadow: bool);
|
||||
|
||||
#[sel(setIgnoresMouseEvents:)]
|
||||
pub fn setIgnoresMouseEvents(&self, ignores: bool);
|
||||
|
||||
#[sel(setBackgroundColor:)]
|
||||
pub fn setBackgroundColor(&self, color: &NSColor);
|
||||
|
||||
#[sel(styleMask)]
|
||||
pub fn styleMask(&self) -> NSWindowStyleMask;
|
||||
|
||||
#[sel(setStyleMask:)]
|
||||
pub fn setStyleMask(&self, mask: NSWindowStyleMask);
|
||||
|
||||
#[sel(registerForDraggedTypes:)]
|
||||
pub fn registerForDraggedTypes(&self, types: &NSArray<NSPasteboardType>);
|
||||
|
||||
#[sel(makeKeyAndOrderFront:)]
|
||||
pub fn makeKeyAndOrderFront(&self, sender: Option<&Object>);
|
||||
|
||||
#[sel(miniaturize:)]
|
||||
pub fn miniaturize(&self, sender: Option<&Object>);
|
||||
|
||||
#[sel(sender:)]
|
||||
pub fn deminiaturize(&self, sender: Option<&Object>);
|
||||
|
||||
#[sel(toggleFullScreen:)]
|
||||
pub fn toggleFullScreen(&self, sender: Option<&Object>);
|
||||
|
||||
#[sel(orderOut:)]
|
||||
pub fn orderOut(&self, sender: Option<&Object>);
|
||||
|
||||
#[sel(zoom:)]
|
||||
pub fn zoom(&self, sender: Option<&Object>);
|
||||
|
||||
#[sel(selectNextKeyView:)]
|
||||
pub fn selectNextKeyView(&self, sender: Option<&Object>);
|
||||
|
||||
#[sel(selectPreviousKeyView:)]
|
||||
pub fn selectPreviousKeyView(&self, sender: Option<&Object>);
|
||||
|
||||
pub fn firstResponder(&self) -> Option<Id<NSResponder, Shared>> {
|
||||
unsafe { msg_send_id![self, firstResponder] }
|
||||
}
|
||||
|
||||
pub fn standardWindowButton(&self, kind: NSWindowButton) -> Option<Id<NSButton, Shared>> {
|
||||
unsafe { msg_send_id![self, standardWindowButton: kind] }
|
||||
}
|
||||
|
||||
#[sel(setTitle:)]
|
||||
pub fn setTitle(&self, title: &NSString);
|
||||
|
||||
#[sel(setReleasedWhenClosed:)]
|
||||
pub fn setReleasedWhenClosed(&self, val: bool);
|
||||
|
||||
#[sel(setAcceptsMouseMovedEvents:)]
|
||||
pub fn setAcceptsMouseMovedEvents(&self, val: bool);
|
||||
|
||||
#[sel(setTitlebarAppearsTransparent:)]
|
||||
pub fn setTitlebarAppearsTransparent(&self, val: bool);
|
||||
|
||||
#[sel(setTitleVisibility:)]
|
||||
pub fn setTitleVisibility(&self, visibility: NSWindowTitleVisibility);
|
||||
|
||||
#[sel(setMovableByWindowBackground:)]
|
||||
pub fn setMovableByWindowBackground(&self, val: bool);
|
||||
|
||||
#[sel(setLevel:)]
|
||||
pub fn setLevel(&self, level: NSWindowLevel);
|
||||
|
||||
#[sel(occlusionState)]
|
||||
pub fn occlusionState(&self) -> NSWindowOcclusionState;
|
||||
|
||||
#[sel(center)]
|
||||
pub fn center(&self);
|
||||
|
||||
#[sel(isResizable)]
|
||||
pub fn isResizable(&self) -> bool;
|
||||
|
||||
#[sel(isMiniaturized)]
|
||||
pub fn isMiniaturized(&self) -> bool;
|
||||
|
||||
#[sel(isVisible)]
|
||||
pub fn isVisible(&self) -> bool;
|
||||
|
||||
#[sel(isZoomed)]
|
||||
pub fn isZoomed(&self) -> bool;
|
||||
|
||||
#[sel(close)]
|
||||
pub fn close(&self);
|
||||
|
||||
#[sel(performWindowDragWithEvent:)]
|
||||
// TODO: Can this actually accept NULL?
|
||||
pub fn performWindowDragWithEvent(&self, event: Option<&NSEvent>);
|
||||
|
||||
#[sel(invalidateCursorRectsForView:)]
|
||||
pub fn invalidateCursorRectsForView(&self, view: &NSView);
|
||||
|
||||
#[sel(setDelegate:)]
|
||||
pub fn setDelegate(&self, delegate: Option<&NSObject>);
|
||||
|
||||
#[sel(sendEvent:)]
|
||||
pub unsafe fn sendEvent(&self, event: &NSEvent);
|
||||
}
|
||||
);
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(isize)] // NSInteger
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum NSWindowTitleVisibility {
|
||||
#[doc(alias = "NSWindowTitleVisible")]
|
||||
Visible = 0,
|
||||
#[doc(alias = "NSWindowTitleHidden")]
|
||||
Hidden = 1,
|
||||
}
|
||||
|
||||
unsafe impl Encode for NSWindowTitleVisibility {
|
||||
const ENCODING: Encoding = NSInteger::ENCODING;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(usize)] // NSUInteger
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum NSWindowButton {
|
||||
#[doc(alias = "NSWindowCloseButton")]
|
||||
Close = 0,
|
||||
#[doc(alias = "NSWindowMiniaturizeButton")]
|
||||
Miniaturize = 1,
|
||||
#[doc(alias = "NSWindowZoomButton")]
|
||||
Zoom = 2,
|
||||
#[doc(alias = "NSWindowToolbarButton")]
|
||||
Toolbar = 3,
|
||||
#[doc(alias = "NSWindowDocumentIconButton")]
|
||||
DocumentIcon = 4,
|
||||
#[doc(alias = "NSWindowDocumentVersionsButton")]
|
||||
DocumentVersions = 6,
|
||||
#[doc(alias = "NSWindowFullScreenButton")]
|
||||
#[deprecated = "Deprecated since macOS 10.12"]
|
||||
FullScreen = 7,
|
||||
}
|
||||
|
||||
unsafe impl Encode for NSWindowButton {
|
||||
const ENCODING: Encoding = NSUInteger::ENCODING;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod window_level_key {
|
||||
use objc2::foundation::NSInteger;
|
||||
pub const kCGBaseWindowLevelKey: NSInteger = 0;
|
||||
pub const kCGMinimumWindowLevelKey: NSInteger = 1;
|
||||
pub const kCGDesktopWindowLevelKey: NSInteger = 2;
|
||||
pub const kCGBackstopMenuLevelKey: NSInteger = 3;
|
||||
pub const kCGNormalWindowLevelKey: NSInteger = 4;
|
||||
pub const kCGFloatingWindowLevelKey: NSInteger = 5;
|
||||
pub const kCGTornOffMenuWindowLevelKey: NSInteger = 6;
|
||||
pub const kCGDockWindowLevelKey: NSInteger = 7;
|
||||
pub const kCGMainMenuWindowLevelKey: NSInteger = 8;
|
||||
pub const kCGStatusWindowLevelKey: NSInteger = 9;
|
||||
pub const kCGModalPanelWindowLevelKey: NSInteger = 10;
|
||||
pub const kCGPopUpMenuWindowLevelKey: NSInteger = 11;
|
||||
pub const kCGDraggingWindowLevelKey: NSInteger = 12;
|
||||
pub const kCGScreenSaverWindowLevelKey: NSInteger = 13;
|
||||
pub const kCGMaximumWindowLevelKey: NSInteger = 14;
|
||||
pub const kCGOverlayWindowLevelKey: NSInteger = 15;
|
||||
pub const kCGHelpWindowLevelKey: NSInteger = 16;
|
||||
pub const kCGUtilityWindowLevelKey: NSInteger = 17;
|
||||
pub const kCGDesktopIconWindowLevelKey: NSInteger = 18;
|
||||
pub const kCGCursorWindowLevelKey: NSInteger = 19;
|
||||
pub const kCGNumberOfWindowLevelKeys: NSInteger = 20;
|
||||
}
|
||||
use window_level_key::*;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[repr(isize)]
|
||||
pub enum NSWindowLevel {
|
||||
#[doc(alias = "NSNormalWindowLevel")]
|
||||
Normal = kCGBaseWindowLevelKey,
|
||||
#[doc(alias = "NSFloatingWindowLevel")]
|
||||
Floating = kCGFloatingWindowLevelKey,
|
||||
#[doc(alias = "NSTornOffMenuWindowLevel")]
|
||||
TornOffMenu = kCGTornOffMenuWindowLevelKey,
|
||||
#[doc(alias = "NSModalPanelWindowLevel")]
|
||||
ModalPanel = kCGModalPanelWindowLevelKey,
|
||||
#[doc(alias = "NSMainMenuWindowLevel")]
|
||||
MainMenu = kCGMainMenuWindowLevelKey,
|
||||
#[doc(alias = "NSStatusWindowLevel")]
|
||||
Status = kCGStatusWindowLevelKey,
|
||||
#[doc(alias = "NSPopUpMenuWindowLevel")]
|
||||
PopUpMenu = kCGPopUpMenuWindowLevelKey,
|
||||
#[doc(alias = "NSScreenSaverWindowLevel")]
|
||||
ScreenSaver = kCGScreenSaverWindowLevelKey,
|
||||
}
|
||||
|
||||
unsafe impl Encode for NSWindowLevel {
|
||||
const ENCODING: Encoding = NSInteger::ENCODING;
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub struct NSWindowOcclusionState: NSUInteger {
|
||||
const NSWindowOcclusionStateVisible = 1 << 1;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Encode for NSWindowOcclusionState {
|
||||
const ENCODING: Encoding = NSUInteger::ENCODING;
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub struct NSWindowStyleMask: NSUInteger {
|
||||
const NSBorderlessWindowMask = 0;
|
||||
const NSTitledWindowMask = 1 << 0;
|
||||
const NSClosableWindowMask = 1 << 1;
|
||||
const NSMiniaturizableWindowMask = 1 << 2;
|
||||
const NSResizableWindowMask = 1 << 3;
|
||||
const NSTexturedBackgroundWindowMask = 1 << 8;
|
||||
const NSUnifiedTitleAndToolbarWindowMask = 1 << 12;
|
||||
const NSFullScreenWindowMask = 1 << 14;
|
||||
const NSFullSizeContentViewWindowMask = 1 << 15;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Encode for NSWindowStyleMask {
|
||||
const ENCODING: Encoding = NSUInteger::ENCODING;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(usize)] // NSUInteger
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum NSBackingStoreType {
|
||||
NSBackingStoreRetained = 0,
|
||||
NSBackingStoreNonretained = 1,
|
||||
NSBackingStoreBuffered = 2,
|
||||
}
|
||||
|
||||
unsafe impl Encode for NSBackingStoreType {
|
||||
const ENCODING: Encoding = NSUInteger::ENCODING;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue