objc2_app_kit/
lib.rs

1//! # Bindings to the `AppKit` framework
2//!
3//! See [Apple's docs][apple-doc] and [the general docs on framework crates][framework-crates] for more information.
4//!
5//! [apple-doc]: https://developer.apple.com/documentation/appkit/
6//! [framework-crates]: https://docs.rs/objc2/latest/objc2/topics/about_generated/index.html
7//!
8//! Note that a lot of functionality in AppKit requires that the application
9//! has initialized properly, which is only done after the application
10//! delegate has received `applicationDidFinishLaunching`.
11//!
12//! You should aspire to do all your UI initialization work in there!
13//!
14//!
15//! ## NSWindow
16//!
17//! Be careful when creating `NSWindow` if it's not inside a window
18//! controller; in those cases you're _required_ to call
19//! `window.releasedWhenClosed(false)` to get correct memory management, which
20//! is also why the creation methods for `NSWindow` are `unsafe`.
21#![no_std]
22#![cfg_attr(feature = "unstable-darwin-objc", feature(darwin_objc))]
23#![cfg_attr(docsrs, feature(doc_cfg))]
24// Update in Cargo.toml as well.
25#![doc(html_root_url = "https://docs.rs/objc2-app-kit/0.3.2")]
26#![recursion_limit = "512"]
27#![allow(non_snake_case)]
28#![allow(unused_imports)]
29#![allow(unreachable_pub)]
30
31#[cfg(feature = "alloc")]
32extern crate alloc;
33
34#[cfg(feature = "std")]
35extern crate std;
36
37#[cfg_attr(feature = "gnustep-1-7", link(name = "gnustep-gui", kind = "dylib"))]
38extern "C" {}
39
40#[cfg(feature = "NSApplication")]
41mod application;
42#[cfg(feature = "NSEvent")]
43mod event;
44mod generated;
45#[cfg(feature = "NSGestureRecognizer")]
46mod gesture_recognizer;
47#[cfg(feature = "NSImage")]
48mod image;
49#[cfg(feature = "NSSlider")]
50mod slider;
51#[cfg(feature = "NSSliderCell")]
52mod slider_cell;
53#[cfg(feature = "NSText")]
54mod text;
55
56#[cfg(feature = "NSApplication")]
57#[cfg(feature = "NSResponder")]
58pub use self::application::*;
59pub use self::generated::*;
60
61/// (!TARGET_CPU_X86_64 || (TARGET_OS_IPHONE && !TARGET_OS_MACCATALYST))
62///
63/// <https://github.com/xamarin/xamarin-macios/issues/12111>
64#[allow(unused)]
65#[allow(unexpected_cfgs)]
66pub(crate) const TARGET_ABI_USES_IOS_VALUES: bool = !cfg!(target_arch = "x86_64")
67    || (cfg!(all(target_vendor = "apple", not(target_os = "macos")))
68        && !cfg!(target_env = "macabi"));
69
70// MacTypes.h
71#[allow(unused)]
72pub(crate) type UTF32Char = u32; // Or maybe Rust's char?
73
74// OpenGL/gltypes.h
75// Not re-exported by objc2-open-gl.
76#[allow(unused)]
77pub(crate) type GLbitfield = u32;
78#[allow(unused)]
79pub(crate) type GLenum = u32;
80#[allow(unused)]
81pub(crate) type GLint = i32;
82#[allow(unused)]
83pub(crate) type GLsizei = i32;
84
85// TODO: Send + Sync for NSColor. Documentation says:
86// > Color objects are immutable and thread-safe
87//
88// But unsure if this applies for things like `-setFill`?
89
90// TODO: Send + Sync for NSCursor. It is immutable, stated here:
91// https://developer.apple.com/documentation/appkit/nscursor/1527062-image?language=objc
92//
93// But unsure if `push`/`pop` methods are safe from non-main threads?
94
95// NOTE: NSEvent is immutable, so it _may_ be possible to make Send + Sync,
96// but let's refrain from doing so, because of:
97// > Safely handled only on the same thread, whether that be the main
98// > thread or a secondary thread; otherwise you run the risk of having
99// > events get out of sequence.
100//
101// <https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CocoaFundamentals/AddingBehaviortoaCocoaProgram/AddingBehaviorCocoa.html#//apple_ref/doc/uid/TP40002974-CH5-SW47>
102// <https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html#//apple_ref/doc/uid/10000057i-CH12-123383>
103
104// NOTE: `NSShadow` is marked as `@unchecked Swift.Sendable` in
105// `AppKit.Framework/Modules/AppKit.swiftmodule/*.swiftinterface`, but
106// only when the deployment target is macOS 14.0 (so we can only do that too
107// when https://github.com/rust-lang/rfcs/pull/3750 lands).
108
109#[cfg(test)]
110mod tests {
111    #[test]
112    #[cfg(feature = "NSAccessibilityProtocols")]
113    fn accessibility_element_protocol() {
114        use crate::NSAccessibilityElementProtocol;
115        use objc2::ProtocolType;
116        let actual = <dyn NSAccessibilityElementProtocol>::NAME;
117        assert_eq!(actual, "NSAccessibilityElement");
118    }
119}