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}