Skip to content

Commit b6f9b68

Browse files
committed
Make handle fields private
This allows structs to define additional safety invariants (which would otherwise be trivial to override by modifying the field). This allows done one of: - Adding reference-counting to platform handles. - Combining `WindowHandle<'_>` and `RawWindowHandle`. Depending on what we want to do in the future.
1 parent 74af1fe commit b6f9b68

2 files changed

Lines changed: 59 additions & 40 deletions

File tree

src/android.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,12 @@ impl DisplayHandle<'static> {
4747
#[non_exhaustive]
4848
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4949
pub struct AndroidNdkWindowHandle {
50-
/// A pointer to an `ANativeWindow`.
51-
pub a_native_window: NonNull<c_void>,
50+
a_native_window: NonNull<c_void>,
5251
}
5352

5453
impl AndroidNdkWindowHandle {
5554
/// Create a new handle to an `ANativeWindow`.
5655
///
57-
///
5856
/// # Example
5957
///
6058
/// ```
@@ -69,4 +67,21 @@ impl AndroidNdkWindowHandle {
6967
pub fn new(a_native_window: NonNull<c_void>) -> Self {
7068
Self { a_native_window }
7169
}
70+
71+
/// A pointer to an `ANativeWindow`.
72+
///
73+
/// # Example
74+
///
75+
/// ```
76+
/// # use core::ptr::NonNull;
77+
/// # use raw_window_handle::AndroidNdkWindowHandle;
78+
/// # type ANativeWindow = ();
79+
/// #
80+
/// # let handle = AndroidNdkWindowHandle::new(NonNull::dangling());
81+
/// let ptr = handle.a_native_window();
82+
/// let ptr = ptr.cast::<ANativeWindow>();
83+
/// ```
84+
pub fn a_native_window(&self) -> NonNull<c_void> {
85+
self.a_native_window
86+
}
7287
}

src/appkit.rs

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -48,46 +48,10 @@ impl DisplayHandle<'static> {
4848
/// Note that `NSView` can only be accessed from the main thread of the
4949
/// application. This struct is `!Send` and `!Sync` to help with ensuring
5050
/// 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::MainThreadMarker;
61-
/// # #[cfg(requires_objc2)]
62-
/// use objc2::rc::Retained;
63-
/// # #[cfg(requires_objc2)]
64-
/// use objc2_app_kit::NSView;
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!(MainThreadMarker::new().is_some(), "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: Retained<NSView> = unsafe { Retained::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-
/// ```
8651
#[non_exhaustive]
8752
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8853
pub struct AppKitWindowHandle {
89-
/// A pointer to an `NSView` object.
90-
pub ns_view: NonNull<c_void>,
54+
ns_view: NonNull<c_void>,
9155
}
9256

9357
impl AppKitWindowHandle {
@@ -112,4 +76,44 @@ impl AppKitWindowHandle {
11276
pub fn new(ns_view: NonNull<c_void>) -> Self {
11377
Self { ns_view }
11478
}
79+
80+
/// A pointer to an `NSView` object.
81+
///
82+
/// # Example
83+
///
84+
/// Getting the view from a [`WindowHandle`][crate::WindowHandle].
85+
///
86+
/// ```no_run
87+
/// # fn inner() {
88+
/// #![cfg(target_os = "macos")]
89+
/// # #[cfg(requires_objc2)]
90+
/// use objc2::MainThreadMarker;
91+
/// # #[cfg(requires_objc2)]
92+
/// use objc2::rc::Retained;
93+
/// # #[cfg(requires_objc2)]
94+
/// use objc2_app_kit::NSView;
95+
/// use raw_window_handle::{WindowHandle, RawWindowHandle};
96+
///
97+
/// let handle: WindowHandle<'_>; // Get the window handle from somewhere else
98+
/// # handle = unimplemented!();
99+
/// match handle.as_raw() {
100+
/// # #[cfg(requires_objc2)]
101+
/// RawWindowHandle::AppKit(handle) => {
102+
/// assert!(MainThreadMarker::new().is_some(), "can only access AppKit handles on the main thread");
103+
/// let ns_view = handle.ns_view().as_ptr();
104+
/// // SAFETY: The pointer came from `WindowHandle`, which ensures
105+
/// // that the `AppKitWindowHandle` contains a valid pointer to an
106+
/// // `NSView`.
107+
/// // Unwrap is fine, since the pointer came from `NonNull`.
108+
/// let ns_view: Retained<NSView> = unsafe { Retained::retain(ns_view.cast()) }.unwrap();
109+
/// // Do something with the NSView here, like getting the `NSWindow`
110+
/// let ns_window = ns_view.window().expect("view was not installed in a window");
111+
/// }
112+
/// handle => unreachable!("unknown handle {handle:?} for platform"),
113+
/// }
114+
/// # }
115+
/// ```
116+
pub fn ns_view(&self) -> NonNull<c_void> {
117+
self.ns_view
118+
}
115119
}

0 commit comments

Comments
 (0)