Skip to content

Commit 7c82d75

Browse files
committed
Make ParentWindowHandle Send+Sync on all platforms
1 parent a9ab1ce commit 7c82d75

3 files changed

Lines changed: 32 additions & 6 deletions

File tree

src/platform/macos/mod.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use dispatch2::MainThreadBound;
1212
pub use error::Error;
1313
use objc2::__framework_prelude::Retained;
1414
use objc2::rc::Weak;
15-
use objc2::MainThreadMarker;
15+
use objc2::{MainThreadMarker, MainThreadOnly};
1616
use objc2_app_kit::NSView;
1717
use raw_window_handle::{DisplayHandle, HasWindowHandle};
1818
use std::fmt;
@@ -69,9 +69,9 @@ impl fmt::Debug for PlatformHandle {
6969
}
7070
}
7171

72-
#[derive(Debug, Clone, PartialEq, Eq)]
72+
#[derive(Debug)]
7373
pub struct ParentWindowHandle {
74-
view: Retained<NSView>,
74+
view: MainThreadBound<Retained<NSView>>,
7575
}
7676

7777
impl ParentWindowHandle {
@@ -80,6 +80,26 @@ impl ParentWindowHandle {
8080
) -> core::result::Result<Self, ParentWindowHandleError> {
8181
let view = extract_raw_window_handle(window.window_handle()?)?;
8282

83-
Ok(Self { view })
83+
let mtm = view.mtm();
84+
Ok(Self { view: MainThreadBound::new(view, mtm) })
8485
}
8586
}
87+
88+
impl Clone for ParentWindowHandle {
89+
fn clone(&self) -> Self {
90+
// SAFETY: We only use Retained::clone, which is thread-safe
91+
let mtm = unsafe { MainThreadMarker::new_unchecked() };
92+
let view = self.view.get(mtm);
93+
Self { view: MainThreadBound::new(view.clone(), mtm) }
94+
}
95+
}
96+
97+
impl PartialEq for ParentWindowHandle {
98+
fn eq(&self, other: &Self) -> bool {
99+
// SAFETY: We only use Retained::eq, which is thread-safe
100+
let mtm = unsafe { MainThreadMarker::new_unchecked() };
101+
Retained::eq(self.view.get(mtm), other.view.get(mtm))
102+
}
103+
}
104+
105+
impl Eq for ParentWindowHandle {}

src/platform/macos/window.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ impl WindowHandle {
3939
let _ = NSApplication::sharedApplication(mtm);
4040

4141
if let Some(parent) = init.settings.parent.take() {
42-
return Self::create_window_parented(init, parent.inner.view, mtm);
42+
return Self::create_window_parented(init, parent.inner.view.into_inner(mtm), mtm);
4343
}
4444

4545
Self::create_window_standalone(init, mtm)
@@ -126,7 +126,7 @@ impl WindowHandle {
126126
let Some(view) = self.view.load() else { return Ok(()) };
127127
let Some(view) = view.inner_ref() else { return Ok(()) };
128128

129-
BaseviewView::set_parent(view, new_parent.view);
129+
BaseviewView::set_parent(view, new_parent.view.into_inner(view.mtm));
130130

131131
Ok(())
132132
}

src/settings.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,12 @@ pub struct ParentWindowHandle {
145145
pub(crate) inner: platform::ParentWindowHandle,
146146
}
147147

148+
// Assert this is Send+Sync
149+
const _: () = {
150+
const fn foo<T: Send + Sync>() {}
151+
foo::<ParentWindowHandle>();
152+
};
153+
148154
impl ParentWindowHandle {
149155
/// Grabs a handle to the given `parent_window`, to later create a child window in it.
150156
pub fn from_window(parent_window: &impl HasWindowHandle) -> Self {

0 commit comments

Comments
 (0)