use icrate::Foundation::{ CGFloat, NSArray, NSInteger, NSObject, NSPoint, NSRect, NSSize, NSString, NSUInteger, }; use objc2::encode::{Encode, Encoding}; use objc2::rc::Id; use objc2::runtime::AnyObject; use objc2::{extern_class, extern_methods, mutability, ClassType}; use super::{ NSButton, NSColor, NSEvent, NSPasteboardType, NSResponder, NSScreen, NSView, NSWindowTabGroup, }; extern_class!( /// Main-Thread-Only! #[derive(Debug, PartialEq, Eq, Hash)] pub struct NSWindow; unsafe impl ClassType for NSWindow { #[inherits(NSObject)] type Super = NSResponder; type Mutability = mutability::InteriorMutable; } ); // Documented as "Main Thread Only", but: // > Thread safe in that you can create and manage them on a secondary thread. // // // // 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 { #[method(frame)] pub(crate) fn frame(&self) -> NSRect; #[method(backingScaleFactor)] pub(crate) fn backingScaleFactor(&self) -> CGFloat; #[method_id(contentView)] pub(crate) fn contentView(&self) -> Id; #[method(setContentView:)] pub(crate) fn setContentView(&self, view: &NSView); #[method(setInitialFirstResponder:)] pub(crate) fn setInitialFirstResponder(&self, view: &NSView); #[method(makeFirstResponder:)] #[must_use] pub(crate) fn makeFirstResponder(&self, responder: Option<&NSResponder>) -> bool; #[method(contentRectForFrameRect:)] pub(crate) fn contentRectForFrameRect(&self, windowFrame: NSRect) -> NSRect; #[method_id(screen)] pub(crate) fn screen(&self) -> Option>; #[method(setContentSize:)] pub(crate) fn setContentSize(&self, contentSize: NSSize); #[method(setFrameTopLeftPoint:)] pub(crate) fn setFrameTopLeftPoint(&self, point: NSPoint); #[method(setMinSize:)] pub(crate) fn setMinSize(&self, minSize: NSSize); #[method(setMaxSize:)] pub(crate) fn setMaxSize(&self, maxSize: NSSize); #[method(setResizeIncrements:)] pub(crate) fn setResizeIncrements(&self, increments: NSSize); #[method(contentResizeIncrements)] pub(crate) fn contentResizeIncrements(&self) -> NSSize; #[method(setContentResizeIncrements:)] pub(crate) fn setContentResizeIncrements(&self, increments: NSSize); #[method(setFrame:display:)] pub(crate) fn setFrame_display(&self, frameRect: NSRect, flag: bool); #[method(setMovable:)] pub(crate) fn setMovable(&self, movable: bool); #[method(setSharingType:)] pub(crate) fn setSharingType(&self, sharingType: NSWindowSharingType); #[method(setTabbingMode:)] pub(crate) fn setTabbingMode(&self, tabbingMode: NSWindowTabbingMode); #[method(setOpaque:)] pub(crate) fn setOpaque(&self, opaque: bool); #[method(hasShadow)] pub(crate) fn hasShadow(&self) -> bool; #[method(setHasShadow:)] pub(crate) fn setHasShadow(&self, has_shadow: bool); #[method(setIgnoresMouseEvents:)] pub(crate) fn setIgnoresMouseEvents(&self, ignores: bool); #[method(setBackgroundColor:)] pub(crate) fn setBackgroundColor(&self, color: &NSColor); #[method(styleMask)] pub(crate) fn styleMask(&self) -> NSWindowStyleMask; #[method(setStyleMask:)] pub(crate) fn setStyleMask(&self, mask: NSWindowStyleMask); #[method(registerForDraggedTypes:)] pub(crate) fn registerForDraggedTypes(&self, types: &NSArray); #[method(makeKeyAndOrderFront:)] pub(crate) fn makeKeyAndOrderFront(&self, sender: Option<&AnyObject>); #[method(orderFront:)] pub(crate) fn orderFront(&self, sender: Option<&AnyObject>); #[method(miniaturize:)] pub(crate) fn miniaturize(&self, sender: Option<&AnyObject>); #[method(deminiaturize:)] pub(crate) fn deminiaturize(&self, sender: Option<&AnyObject>); #[method(toggleFullScreen:)] pub(crate) fn toggleFullScreen(&self, sender: Option<&AnyObject>); #[method(orderOut:)] pub(crate) fn orderOut(&self, sender: Option<&AnyObject>); #[method(zoom:)] pub(crate) fn zoom(&self, sender: Option<&AnyObject>); #[method(selectNextKeyView:)] pub(crate) fn selectNextKeyView(&self, sender: Option<&AnyObject>); #[method(selectPreviousKeyView:)] pub(crate) fn selectPreviousKeyView(&self, sender: Option<&AnyObject>); #[method_id(firstResponder)] pub(crate) fn firstResponder(&self) -> Option>; #[method_id(standardWindowButton:)] pub(crate) fn standardWindowButton(&self, kind: NSWindowButton) -> Option>; #[method(setTitle:)] pub(crate) fn setTitle(&self, title: &NSString); #[method_id(title)] pub(crate) fn title_(&self) -> Id; #[method(setReleasedWhenClosed:)] pub(crate) fn setReleasedWhenClosed(&self, val: bool); #[method(setAcceptsMouseMovedEvents:)] pub(crate) fn setAcceptsMouseMovedEvents(&self, val: bool); #[method(setTitlebarAppearsTransparent:)] pub(crate) fn setTitlebarAppearsTransparent(&self, val: bool); #[method(setTitleVisibility:)] pub(crate) fn setTitleVisibility(&self, visibility: NSWindowTitleVisibility); #[method(setMovableByWindowBackground:)] pub(crate) fn setMovableByWindowBackground(&self, val: bool); #[method(setLevel:)] pub(crate) fn setLevel(&self, level: NSWindowLevel); #[method(setAllowsAutomaticWindowTabbing:)] pub(crate) fn setAllowsAutomaticWindowTabbing(val: bool); #[method(setTabbingIdentifier:)] pub(crate) fn setTabbingIdentifier(&self, identifier: &NSString); #[method(setDocumentEdited:)] pub(crate) fn setDocumentEdited(&self, val: bool); #[method(occlusionState)] pub(crate) fn occlusionState(&self) -> NSWindowOcclusionState; #[method(center)] pub(crate) fn center(&self); #[method(isResizable)] pub(crate) fn isResizable(&self) -> bool; #[method(isMiniaturizable)] pub(crate) fn isMiniaturizable(&self) -> bool; #[method(hasCloseBox)] pub(crate) fn hasCloseBox(&self) -> bool; #[method(isMiniaturized)] pub(crate) fn isMiniaturized(&self) -> bool; #[method(isVisible)] pub(crate) fn isVisible(&self) -> bool; #[method(isKeyWindow)] pub(crate) fn isKeyWindow(&self) -> bool; #[method(isZoomed)] pub(crate) fn isZoomed(&self) -> bool; #[method(allowsAutomaticWindowTabbing)] pub(crate) fn allowsAutomaticWindowTabbing() -> bool; #[method(selectNextTab)] pub(crate) fn selectNextTab(&self); #[method_id(tabbingIdentifier)] pub(crate) fn tabbingIdentifier(&self) -> Id; #[method_id(tabGroup)] pub(crate) fn tabGroup(&self) -> Option>; #[method(isDocumentEdited)] pub(crate) fn isDocumentEdited(&self) -> bool; #[method(close)] pub(crate) fn close(&self); #[method(performWindowDragWithEvent:)] // TODO: Can this actually accept NULL? pub(crate) fn performWindowDragWithEvent(&self, event: Option<&NSEvent>); #[method(invalidateCursorRectsForView:)] pub(crate) fn invalidateCursorRectsForView(&self, view: &NSView); #[method(setDelegate:)] pub(crate) fn setDelegate(&self, delegate: Option<&NSObject>); #[method(sendEvent:)] pub(crate) unsafe fn sendEvent(&self, event: &NSEvent); #[method(addChildWindow:ordered:)] pub(crate) unsafe fn addChildWindow(&self, child: &NSWindow, ordered: NSWindowOrderingMode); } ); #[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; } // CGWindowLevel.h // // Note: There are two different things at play in this header: // `CGWindowLevel` and `CGWindowLevelKey`. // // It seems like there was a push towards using "key" values instead of the // raw window level values, and then you were supposed to use // `CGWindowLevelForKey` to get the actual level. // // But the values that `NSWindowLevel` has are compiled in, and as such has // to remain ABI compatible, so they're safe for us to hardcode as well. #[allow(dead_code)] mod window_level { const kCGNumReservedWindowLevels: i32 = 16; const kCGNumReservedBaseWindowLevels: i32 = 5; pub const kCGBaseWindowLevel: i32 = i32::MIN; pub const kCGMinimumWindowLevel: i32 = kCGBaseWindowLevel + kCGNumReservedBaseWindowLevels; pub const kCGMaximumWindowLevel: i32 = i32::MAX - kCGNumReservedWindowLevels; pub const kCGDesktopWindowLevel: i32 = kCGMinimumWindowLevel + 20; pub const kCGDesktopIconWindowLevel: i32 = kCGDesktopWindowLevel + 20; pub const kCGBackstopMenuLevel: i32 = -20; pub const kCGNormalWindowLevel: i32 = 0; pub const kCGFloatingWindowLevel: i32 = 3; pub const kCGTornOffMenuWindowLevel: i32 = 3; pub const kCGModalPanelWindowLevel: i32 = 8; pub const kCGUtilityWindowLevel: i32 = 19; pub const kCGDockWindowLevel: i32 = 20; pub const kCGMainMenuWindowLevel: i32 = 24; pub const kCGStatusWindowLevel: i32 = 25; pub const kCGPopUpMenuWindowLevel: i32 = 101; pub const kCGOverlayWindowLevel: i32 = 102; pub const kCGHelpWindowLevel: i32 = 200; pub const kCGDraggingWindowLevel: i32 = 500; pub const kCGScreenSaverWindowLevel: i32 = 1000; pub const kCGAssistiveTechHighWindowLevel: i32 = 1500; pub const kCGCursorWindowLevel: i32 = kCGMaximumWindowLevel - 1; } use window_level::*; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[repr(transparent)] pub struct NSWindowLevel(pub NSInteger); #[allow(dead_code)] impl NSWindowLevel { #[doc(alias = "BelowNormalWindowLevel")] pub const BELOW_NORMAL: Self = Self((kCGNormalWindowLevel - 1) as _); #[doc(alias = "NSNormalWindowLevel")] pub const Normal: Self = Self(kCGNormalWindowLevel as _); #[doc(alias = "NSFloatingWindowLevel")] pub const Floating: Self = Self(kCGFloatingWindowLevel as _); #[doc(alias = "NSTornOffMenuWindowLevel")] pub const TornOffMenu: Self = Self(kCGTornOffMenuWindowLevel as _); #[doc(alias = "NSModalPanelWindowLevel")] pub const ModalPanel: Self = Self(kCGModalPanelWindowLevel as _); #[doc(alias = "NSMainMenuWindowLevel")] pub const MainMenu: Self = Self(kCGMainMenuWindowLevel as _); #[doc(alias = "NSStatusWindowLevel")] pub const Status: Self = Self(kCGStatusWindowLevel as _); #[doc(alias = "NSPopUpMenuWindowLevel")] pub const PopUpMenu: Self = Self(kCGPopUpMenuWindowLevel as _); #[doc(alias = "NSScreenSaverWindowLevel")] pub const ScreenSaver: Self = Self(kCGScreenSaverWindowLevel as _); } unsafe impl Encode for NSWindowLevel { const ENCODING: Encoding = NSInteger::ENCODING; } bitflags! { #[derive(Clone, Copy)] pub struct NSWindowOcclusionState: NSUInteger { const NSWindowOcclusionStateVisible = 1 << 1; } } unsafe impl Encode for NSWindowOcclusionState { const ENCODING: Encoding = NSUInteger::ENCODING; } bitflags! { #[derive(Debug, Clone, Copy)] 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; } #[allow(dead_code)] #[repr(usize)] // NSUInteger #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum NSWindowSharingType { NSWindowSharingNone = 0, NSWindowSharingReadOnly = 1, NSWindowSharingReadWrite = 2, } unsafe impl Encode for NSWindowSharingType { const ENCODING: Encoding = NSUInteger::ENCODING; } #[allow(dead_code)] #[repr(isize)] // NSInteger #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum NSWindowOrderingMode { NSWindowAbove = 1, NSWindowBelow = -1, NSWindowOut = 0, } unsafe impl Encode for NSWindowOrderingMode { const ENCODING: Encoding = NSInteger::ENCODING; } #[allow(dead_code)] #[repr(isize)] // NSInteger #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum NSWindowTabbingMode { NSWindowTabbingModeAutomatic = 0, NSWindowTabbingModeDisallowed = 2, NSWindowTabbingModePreferred = 1, } unsafe impl Encode for NSWindowTabbingMode { const ENCODING: Encoding = NSInteger::ENCODING; }