From e784ebca9f5513ce07b63c15ccac4f51c14efe2f Mon Sep 17 00:00:00 2001 From: Lucas Fernandes Nogueira Date: Thu, 30 Dec 2021 13:46:05 -0300 Subject: [PATCH] fix(core): Send+Sync for Window, closes #3135 (#3140) --- core/tauri-runtime-wry/src/lib.rs | 21 +++++++++++++++++++-- core/tauri/src/app.rs | 18 ++++++++++++++++++ core/tauri/src/lib.rs | 3 +++ core/tauri/src/window.rs | 9 +++++++++ 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/core/tauri-runtime-wry/src/lib.rs b/core/tauri-runtime-wry/src/lib.rs index d5b31233e..8c055e4f3 100644 --- a/core/tauri-runtime-wry/src/lib.rs +++ b/core/tauri-runtime-wry/src/lib.rs @@ -175,7 +175,7 @@ struct DispatcherMainThreadContext { tray_context: TrayContext, } -// the main thread context is only used on the main thread +// SAFETY: we ensure this type is only used on the main thread. #[allow(clippy::non_send_fields_in_send_ty)] unsafe impl Send for DispatcherMainThreadContext {} @@ -376,6 +376,7 @@ impl From for NativeImageWrapper { #[derive(Debug, Clone)] pub struct GlobalShortcutWrapper(GlobalShortcut); +// SAFETY: usage outside of main thread is guarded, we use the event loop on such cases. #[allow(clippy::non_send_fields_in_send_ty)] unsafe impl Send for GlobalShortcutWrapper {} @@ -387,6 +388,10 @@ pub struct GlobalShortcutManagerHandle { listeners: GlobalShortcutListeners, } +// SAFETY: this is safe since the `Context` usage is guarded on `send_user_message`. +#[allow(clippy::non_send_fields_in_send_ty)] +unsafe impl Sync for GlobalShortcutManagerHandle {} + impl fmt::Debug for GlobalShortcutManagerHandle { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("GlobalShortcutManagerHandle") @@ -460,6 +465,10 @@ pub struct ClipboardManagerWrapper { context: Context, } +// SAFETY: this is safe since the `Context` usage is guarded on `send_user_message`. +#[allow(clippy::non_send_fields_in_send_ty)] +unsafe impl Sync for ClipboardManagerWrapper {} + impl ClipboardManager for ClipboardManagerWrapper { fn read_text(&self) -> Result> { let (tx, rx) = channel(); @@ -695,7 +704,7 @@ pub struct WindowBuilderWrapper { menu: Option, } -// safe since `menu_items` are read only here +// SAFETY: this type is `Send` since `menu_items` are read only here #[allow(clippy::non_send_fields_in_send_ty)] unsafe impl Send for WindowBuilderWrapper {} @@ -1053,6 +1062,10 @@ pub struct WryDispatcher { context: Context, } +// SAFETY: this is safe since the `Context` usage is guarded on `send_user_message`. +#[allow(clippy::non_send_fields_in_send_ty)] +unsafe impl Sync for WryDispatcher {} + impl Dispatch for WryDispatcher { type Runtime = Wry; type WindowBuilder = WindowBuilderWrapper; @@ -1486,6 +1499,10 @@ pub struct WryHandle { context: Context, } +// SAFETY: this is safe since the `Context` usage is guarded on `send_user_message`. +#[allow(clippy::non_send_fields_in_send_ty)] +unsafe impl Sync for WryHandle {} + impl WryHandle { /// Creates a new tao window using a callback, and returns its window id. pub fn create_tao_window (String, WryWindowBuilder) + Send + 'static>( diff --git a/core/tauri/src/app.rs b/core/tauri/src/app.rs index 1804cd47e..20e08a832 100644 --- a/core/tauri/src/app.rs +++ b/core/tauri/src/app.rs @@ -1147,3 +1147,21 @@ impl Default for Builder { Self::new() } } + +#[cfg(test)] +mod tests { + #[test] + fn is_send_sync() { + crate::test::assert_send::(); + crate::test::assert_sync::(); + + #[cfg(feature = "wry")] + { + crate::test::assert_send::>(); + crate::test::assert_sync::>(); + } + + crate::test::assert_send::(); + crate::test::assert_sync::(); + } +} diff --git a/core/tauri/src/lib.rs b/core/tauri/src/lib.rs index 166b7d9b8..0f0565556 100644 --- a/core/tauri/src/lib.rs +++ b/core/tauri/src/lib.rs @@ -392,6 +392,9 @@ pub(crate) mod sealed { mod test { use proptest::prelude::*; + pub fn assert_send() {} + pub fn assert_sync() {} + proptest! { #![proptest_config(ProptestConfig::with_cases(10000))] #[test] diff --git a/core/tauri/src/window.rs b/core/tauri/src/window.rs index 22b639e3d..8681bc4d6 100644 --- a/core/tauri/src/window.rs +++ b/core/tauri/src/window.rs @@ -713,3 +713,12 @@ impl Window { self.window.dispatcher.start_dragging().map_err(Into::into) } } + +#[cfg(test)] +mod tests { + #[test] + fn window_is_send_sync() { + crate::test::assert_send::(); + crate::test::assert_sync::(); + } +}