From 3c52f30ea4ec29c51f7021aa7871614d72e43258 Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Wed, 21 Aug 2024 17:04:03 +0300 Subject: [PATCH] chore(deps): update windows-sys crate to `0.59` and global-hotkey to `0.6` (#1665) * chore(deps): update windows-sys crate to `0.59` * update global-hotkey as well * change files --- .changes/global-shortcut-0.6.md | 5 ++ .changes/single-instance-windows-sys.0.59.md | 5 ++ Cargo.lock | 10 ++-- plugins/global-shortcut/Cargo.toml | 2 +- plugins/global-shortcut/src/error.rs | 5 ++ plugins/global-shortcut/src/lib.rs | 53 +++++++++++++------ plugins/single-instance/Cargo.toml | 2 +- .../src/platform_impl/windows.rs | 24 ++++----- 8 files changed, 72 insertions(+), 34 deletions(-) create mode 100644 .changes/global-shortcut-0.6.md create mode 100644 .changes/single-instance-windows-sys.0.59.md diff --git a/.changes/global-shortcut-0.6.md b/.changes/global-shortcut-0.6.md new file mode 100644 index 000000000..c65d9e1a1 --- /dev/null +++ b/.changes/global-shortcut-0.6.md @@ -0,0 +1,5 @@ +--- +"global-shortcut": "patch" +--- + +Updated `global-hotkey` crate dependency to `0.6` diff --git a/.changes/single-instance-windows-sys.0.59.md b/.changes/single-instance-windows-sys.0.59.md new file mode 100644 index 000000000..7f7af0011 --- /dev/null +++ b/.changes/single-instance-windows-sys.0.59.md @@ -0,0 +1,5 @@ +--- +"single-instance": "patch" +--- + +Updated `windows-sys` crate to `0.59` diff --git a/Cargo.lock b/Cargo.lock index 68cfaf1ff..302518d1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2565,19 +2565,19 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "global-hotkey" -version = "0.5.5" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b436093d1598b05e3b7fddc097b2bad32763f53a1beb25ab6f9718c6a60acd09" +checksum = "298a7667d6011efe6b35673c6b29001b88677ae1b3d6b2feccfbff4b44892866" dependencies = [ "bitflags 2.6.0", - "cocoa 0.25.0", + "cocoa 0.26.0", "crossbeam-channel", "keyboard-types", "objc", "once_cell", "serde", "thiserror", - "windows-sys 0.52.0", + "windows-sys 0.59.0", "x11-dl", ] @@ -6840,7 +6840,7 @@ dependencies = [ "serde_json", "tauri", "thiserror", - "windows-sys 0.52.0", + "windows-sys 0.59.0", "zbus", ] diff --git a/plugins/global-shortcut/Cargo.toml b/plugins/global-shortcut/Cargo.toml index 2eec1eb43..02e963fde 100644 --- a/plugins/global-shortcut/Cargo.toml +++ b/plugins/global-shortcut/Cargo.toml @@ -24,4 +24,4 @@ log = { workspace = true } thiserror = { workspace = true } [target."cfg(not(any(target_os = \"android\", target_os = \"ios\")))".dependencies] -global-hotkey = { version = "0.5", features = ["serde"] } +global-hotkey = { version = "0.6", features = ["serde"] } diff --git a/plugins/global-shortcut/src/error.rs b/plugins/global-shortcut/src/error.rs index a1e366a79..37392b321 100644 --- a/plugins/global-shortcut/src/error.rs +++ b/plugins/global-shortcut/src/error.rs @@ -5,9 +5,14 @@ use serde::{Serialize, Serializer}; #[derive(Debug, thiserror::Error)] +#[non_exhaustive] pub enum Error { #[error("{0}")] GlobalHotkey(String), + #[error(transparent)] + RecvError(#[from] std::sync::mpsc::RecvError), + #[error(transparent)] + Tauri(#[from] tauri::Error), } impl Serialize for Error { diff --git a/plugins/global-shortcut/src/lib.rs b/plugins/global-shortcut/src/lib.rs index c472e7269..5868ff9dc 100644 --- a/plugins/global-shortcut/src/lib.rs +++ b/plugins/global-shortcut/src/lib.rs @@ -20,11 +20,11 @@ use std::{ sync::{Arc, Mutex}, }; +use global_hotkey::GlobalHotKeyEvent; pub use global_hotkey::{ hotkey::{Code, HotKey as Shortcut, Modifiers}, GlobalHotKeyEvent as ShortcutEvent, HotKeyState as ShortcutState, }; -use global_hotkey::{GlobalHotKeyEvent, GlobalHotKeyManager}; use serde::Serialize; use tauri::{ ipc::Channel, @@ -60,13 +60,33 @@ struct RegisteredShortcut { handler: Option>>, } +struct GlobalHotKeyManager(global_hotkey::GlobalHotKeyManager); + +/// SAFETY: we ensure it is run on main thread only +unsafe impl Send for GlobalHotKeyManager {} +/// SAFETY: we ensure it is run on main thread only +unsafe impl Sync for GlobalHotKeyManager {} + pub struct GlobalShortcut { #[allow(dead_code)] app: AppHandle, - manager: GlobalHotKeyManager, + manager: Arc, shortcuts: Arc>>>, } +macro_rules! run_main_thread { + ($handle:expr, $manager:expr, |$m:ident| $ex:expr) => {{ + let (tx, rx) = std::sync::mpsc::channel(); + let manager = $manager.clone(); + let task = move || { + let f = |$m: &GlobalHotKeyManager| $ex; + let _ = tx.send(f(&*manager)); + }; + $handle.run_on_main_thread(task)?; + rx.recv()? + }}; +} + impl GlobalShortcut { fn register_internal, &Shortcut, ShortcutEvent) + Send + Sync + 'static>( &self, @@ -75,8 +95,7 @@ impl GlobalShortcut { ) -> Result<()> { let id = shortcut.id(); let handler = handler.map(|h| Arc::new(Box::new(h) as HandlerFn)); - - self.manager.register(shortcut)?; + run_main_thread!(self.app, self.manager, |m| m.0.register(shortcut))?; self.shortcuts .lock() .unwrap() @@ -95,7 +114,7 @@ impl GlobalShortcut { let mut shortcuts = self.shortcuts.lock().unwrap(); for shortcut in hotkeys { - self.manager.register(shortcut)?; + run_main_thread!(self.app, self.manager, |m| m.0.register(shortcut))?; shortcuts.insert( shortcut.id(), RegisteredShortcut { @@ -167,7 +186,7 @@ impl GlobalShortcut { S::Error: std::error::Error, { let shortcut = try_into_shortcut(shortcut)?; - self.manager.unregister(shortcut)?; + run_main_thread!(self.app, self.manager, |m| m.0.unregister(shortcut))?; self.shortcuts.lock().unwrap().remove(&shortcut.id()); Ok(()) } @@ -180,15 +199,19 @@ impl GlobalShortcut { where T::Error: std::error::Error, { - let mut s = Vec::new(); + let mut mapped_shortcuts = Vec::new(); for shortcut in shortcuts { - s.push(try_into_shortcut(shortcut)?); + mapped_shortcuts.push(try_into_shortcut(shortcut)?); } - self.manager.unregister_all(&s)?; + { + let mapped_shortcuts = mapped_shortcuts.clone(); + #[rustfmt::skip] + run_main_thread!(self.app, self.manager, |m| m.0.unregister_all(&mapped_shortcuts))?; + } let mut shortcuts = self.shortcuts.lock().unwrap(); - for s in s { + for s in mapped_shortcuts { shortcuts.remove(&s.id()); } @@ -200,9 +223,9 @@ impl GlobalShortcut { let mut shortcuts = self.shortcuts.lock().unwrap(); let hotkeys = std::mem::take(&mut *shortcuts); let hotkeys = hotkeys.values().map(|s| s.shortcut).collect::>(); - self.manager - .unregister_all(hotkeys.as_slice()) - .map_err(Into::into) + #[rustfmt::skip] + let res = run_main_thread!(self.app, self.manager, |m| m.0.unregister_all(hotkeys.as_slice())); + res.map_err(Into::into) } /// Determines whether the given shortcut is registered by this application or not. @@ -375,7 +398,7 @@ impl Builder { is_registered, ]) .setup(move |app, _api| { - let manager = GlobalHotKeyManager::new()?; + let manager = global_hotkey::GlobalHotKeyManager::new()?; let mut store = HashMap::>::new(); for shortcut in shortcuts { manager.register(shortcut)?; @@ -405,7 +428,7 @@ impl Builder { app.manage(GlobalShortcut { app: app.clone(), - manager, + manager: Arc::new(GlobalHotKeyManager(manager)), shortcuts, }); Ok(()) diff --git a/plugins/single-instance/Cargo.toml b/plugins/single-instance/Cargo.toml index bc05e33f0..df827c405 100644 --- a/plugins/single-instance/Cargo.toml +++ b/plugins/single-instance/Cargo.toml @@ -22,7 +22,7 @@ thiserror = { workspace = true } semver = { version = "1", optional = true } [target."cfg(target_os = \"windows\")".dependencies.windows-sys] -version = "0.52" +version = "0.59" features = [ "Win32_System_Threading", "Win32_System_DataExchange", diff --git a/plugins/single-instance/src/platform_impl/windows.rs b/plugins/single-instance/src/platform_impl/windows.rs index d5ff3b8ba..e99f405d0 100644 --- a/plugins/single-instance/src/platform_impl/windows.rs +++ b/plugins/single-instance/src/platform_impl/windows.rs @@ -53,7 +53,7 @@ pub fn init(f: Box>) -> TauriPlugin { unsafe { let hwnd = FindWindowW(class_name.as_ptr(), window_name.as_ptr()); - if hwnd != 0 { + if !hwnd.is_null() { let data = format!( "{}|{}\0", std::env::current_dir() @@ -74,7 +74,7 @@ pub fn init(f: Box>) -> TauriPlugin { } } } else { - app.manage(MutexHandle(hmutex)); + app.manage(MutexHandle(hmutex as _)); let hwnd = create_event_target_window::(&class_name, &window_name); unsafe { @@ -85,7 +85,7 @@ pub fn init(f: Box>) -> TauriPlugin { ) }; - app.manage(TargetWindowHandle(hwnd)); + app.manage(TargetWindowHandle(hwnd as _)); } Ok(()) @@ -101,12 +101,12 @@ pub fn init(f: Box>) -> TauriPlugin { pub fn destroy>(manager: &M) { if let Some(hmutex) = manager.try_state::() { unsafe { - ReleaseMutex(hmutex.0); - CloseHandle(hmutex.0); + ReleaseMutex(hmutex.0 as _); + CloseHandle(hmutex.0 as _); } } if let Some(hwnd) = manager.try_state::() { - unsafe { DestroyWindow(hwnd.0) }; + unsafe { DestroyWindow(hwnd.0 as _) }; } } @@ -150,12 +150,12 @@ fn create_event_target_window(class_name: &[u16], window_name: &[u16 cbClsExtra: 0, cbWndExtra: 0, hInstance: GetModuleHandleW(std::ptr::null()), - hIcon: 0, - hCursor: 0, - hbrBackground: 0, + hIcon: std::ptr::null_mut(), + hCursor: std::ptr::null_mut(), + hbrBackground: std::ptr::null_mut(), lpszMenuName: std::ptr::null(), lpszClassName: class_name.as_ptr(), - hIconSm: 0, + hIconSm: std::ptr::null_mut(), }; RegisterClassExW(&class); @@ -179,8 +179,8 @@ fn create_event_target_window(class_name: &[u16], window_name: &[u16 0, 0, 0, - 0, - 0, + std::ptr::null_mut(), + std::ptr::null_mut(), GetModuleHandleW(std::ptr::null()), std::ptr::null(), );