raw_window_handle/
appkit.rs

1use core::ffi::c_void;
2use core::ptr::NonNull;
3
4use super::DisplayHandle;
5
6/// Raw display handle for AppKit.
7#[non_exhaustive]
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9pub struct AppKitDisplayHandle {}
10
11impl AppKitDisplayHandle {
12    /// Create a new empty display handle.
13    ///
14    ///
15    /// # Example
16    ///
17    /// ```
18    /// # use raw_window_handle::AppKitDisplayHandle;
19    /// let handle = AppKitDisplayHandle::new();
20    /// ```
21    pub fn new() -> Self {
22        Self {}
23    }
24}
25
26impl DisplayHandle<'static> {
27    /// Create an AppKit-based display handle.
28    ///
29    /// As no data is borrowed by this handle, it is completely safe to create. This function
30    /// may be useful to windowing framework implementations that want to avoid unsafe code.
31    ///
32    /// # Example
33    ///
34    /// ```
35    /// # use raw_window_handle::{DisplayHandle, HasDisplayHandle};
36    /// # fn do_something(rwh: impl HasDisplayHandle) { let _ = rwh; }
37    /// let handle = DisplayHandle::appkit();
38    /// do_something(handle);
39    /// ```
40    pub fn appkit() -> Self {
41        // SAFETY: No data is borrowed.
42        unsafe { Self::borrow_raw(AppKitDisplayHandle::new().into()) }
43    }
44}
45
46/// Raw window handle for AppKit.
47///
48/// Note that `NSView` can only be accessed from the main thread of the
49/// application. This struct is `!Send` and `!Sync` to help with ensuring
50/// that.
51///
52/// # Example
53///
54/// Getting the view from a [`WindowHandle`][crate::WindowHandle].
55///
56/// ```no_run
57/// # fn inner() {
58/// #![cfg(target_os = "macos")]
59/// # #[cfg(requires_objc2)]
60/// use objc2_app_kit::NSView;
61/// # #[cfg(requires_objc2)]
62/// use objc2_foundation::is_main_thread;
63/// # #[cfg(requires_objc2)]
64/// use objc2::rc::Id;
65/// use raw_window_handle::{WindowHandle, RawWindowHandle};
66///
67/// let handle: WindowHandle<'_>; // Get the window handle from somewhere else
68/// # handle = unimplemented!();
69/// match handle.as_raw() {
70///     # #[cfg(requires_objc2)]
71///     RawWindowHandle::AppKit(handle) => {
72///         assert!(is_main_thread(), "can only access AppKit handles on the main thread");
73///         let ns_view = handle.ns_view.as_ptr();
74///         // SAFETY: The pointer came from `WindowHandle`, which ensures
75///         // that the `AppKitWindowHandle` contains a valid pointer to an
76///         // `NSView`.
77///         // Unwrap is fine, since the pointer came from `NonNull`.
78///         let ns_view: Id<NSView> = unsafe { Id::retain(ns_view.cast()) }.unwrap();
79///         // Do something with the NSView here, like getting the `NSWindow`
80///         let ns_window = ns_view.window().expect("view was not installed in a window");
81///     }
82///     handle => unreachable!("unknown handle {handle:?} for platform"),
83/// }
84/// # }
85/// ```
86#[non_exhaustive]
87#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
88pub struct AppKitWindowHandle {
89    /// A pointer to an `NSView` object.
90    pub ns_view: NonNull<c_void>,
91}
92
93impl AppKitWindowHandle {
94    /// Create a new handle to a view.
95    ///
96    ///
97    /// # Example
98    ///
99    /// ```
100    /// # use core::ptr::NonNull;
101    /// # use raw_window_handle::AppKitWindowHandle;
102    /// # type NSView = ();
103    /// #
104    /// let view: &NSView;
105    /// # view = &();
106    /// let handle = AppKitWindowHandle::new(NonNull::from(view).cast());
107    /// ```
108    pub fn new(ns_view: NonNull<c_void>) -> Self {
109        Self { ns_view }
110    }
111}