fix(core): Send+Sync for Window, closes #3135 (#3140)

This commit is contained in:
Lucas Fernandes Nogueira
2021-12-30 13:46:05 -03:00
committed by GitHub
parent efbf236f35
commit e784ebca9f
4 changed files with 49 additions and 2 deletions

View File

@@ -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<NativeImage> 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<Option<String>> {
let (tx, rx) = channel();
@@ -695,7 +704,7 @@ pub struct WindowBuilderWrapper {
menu: Option<Menu>,
}
// 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<F: FnOnce() -> (String, WryWindowBuilder) + Send + 'static>(

View File

@@ -1147,3 +1147,21 @@ impl Default for Builder<crate::Wry> {
Self::new()
}
}
#[cfg(test)]
mod tests {
#[test]
fn is_send_sync() {
crate::test::assert_send::<super::AppHandle>();
crate::test::assert_sync::<super::AppHandle>();
#[cfg(feature = "wry")]
{
crate::test::assert_send::<super::AssetResolver<crate::Wry>>();
crate::test::assert_sync::<super::AssetResolver<crate::Wry>>();
}
crate::test::assert_send::<super::PathResolver>();
crate::test::assert_sync::<super::PathResolver>();
}
}

View File

@@ -392,6 +392,9 @@ pub(crate) mod sealed {
mod test {
use proptest::prelude::*;
pub fn assert_send<T: Send>() {}
pub fn assert_sync<T: Sync>() {}
proptest! {
#![proptest_config(ProptestConfig::with_cases(10000))]
#[test]

View File

@@ -713,3 +713,12 @@ impl<R: Runtime> Window<R> {
self.window.dispatcher.start_dragging().map_err(Into::into)
}
}
#[cfg(test)]
mod tests {
#[test]
fn window_is_send_sync() {
crate::test::assert_send::<super::Window>();
crate::test::assert_sync::<super::Window>();
}
}