From 8bddf30dcf1603ad7eb0959d912e497d2bbff8db Mon Sep 17 00:00:00 2001 From: GyDi Date: Fri, 23 Sep 2022 15:31:01 +0800 Subject: [PATCH] refactor(hotkey): use tauri global shortcut --- src-tauri/Cargo.lock | 46 -------- src-tauri/Cargo.toml | 3 +- src-tauri/src/core/hotkey.rs | 100 +++++++++--------- src-tauri/src/core/mod.rs | 4 +- src-tauri/tauri.conf.json | 3 + src/components/setting/mods/hotkey-viewer.tsx | 4 +- 6 files changed, 58 insertions(+), 102 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index f51c078..3a8d1cd 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -539,7 +539,6 @@ dependencies = [ "sysproxy", "tauri", "tauri-build", - "tauri-hotkey", "tokio", "warp", "which 4.3.0", @@ -3785,24 +3784,6 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" -[[package]] -name = "strum" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7318c509b5ba57f18533982607f24070a55d353e90d4cae30c467cdb2ad5ac5c" - -[[package]] -name = "strum_macros" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee8bc6b87a5112aeeab1f4a9f7ab634fe6cbefc4850006df31267f4cfb9e3149" -dependencies = [ - "heck 0.3.3", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "syn" version = "1.0.100" @@ -4022,33 +4003,6 @@ dependencies = [ "walkdir", ] -[[package]] -name = "tauri-hotkey" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6cf71018e75b7c88f0c9643329891668c32cb377a1cccdd1f2973f51eff118" -dependencies = [ - "log 0.4.17", - "once_cell", - "serde", - "strum", - "strum_macros", - "tauri-hotkey-sys", - "thiserror", -] - -[[package]] -name = "tauri-hotkey-sys" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7024154106177cefd2592bcb0bb3df9dd3aea8a7e21f8fefb8d5b02fe115fed7" -dependencies = [ - "cc", - "thiserror", - "winapi", - "x11-dl", -] - [[package]] name = "tauri-macros" version = "1.1.1" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 6a8f6c6..6735c86 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -33,11 +33,10 @@ once_cell = "1.14.0" port_scanner = "0.1.5" delay_timer = "0.11.1" parking_lot = "0.12.0" -tauri-hotkey = "0.1.2" tokio = { version = "1", features = ["full"] } serde = { version = "1.0", features = ["derive"] } reqwest = { version = "0.11", features = ["json"] } -tauri = { version = "1.1.1", features = ["process-all", "shell-all", "system-tray", "updater", "window-all"] } +tauri = { version = "1.1.1", features = ["global-shortcut-all", "process-all", "shell-all", "system-tray", "updater", "window-all"] } rquickjs = { version = "0.1.7" } window-shadows = { version = "0.2.0" } window-vibrancy = { version = "0.3.0" } diff --git a/src-tauri/src/core/hotkey.rs b/src-tauri/src/core/hotkey.rs index 815a2e4..7446746 100644 --- a/src-tauri/src/core/hotkey.rs +++ b/src-tauri/src/core/hotkey.rs @@ -1,22 +1,23 @@ use crate::{data::*, feat, log_if_err}; use anyhow::{bail, Result}; use std::collections::HashMap; -use tauri_hotkey::{parse_hotkey, HotkeyManager}; +use tauri::{AppHandle, GlobalShortcutManager}; pub struct Hotkey { current: Vec, // 保存当前的热键设置 - manager: HotkeyManager, + manager: Option, } impl Hotkey { pub fn new() -> Hotkey { Hotkey { current: Vec::new(), - manager: HotkeyManager::new(), + manager: None, } } - pub fn init(&mut self) -> Result<()> { + pub fn init(&mut self, app_handle: AppHandle) -> Result<()> { + self.manager = Some(app_handle); let data = Data::global(); let verge = data.verge.lock(); @@ -27,9 +28,9 @@ impl Hotkey { let key = iter.next(); if func.is_some() && key.is_some() { - log_if_err!(self.register(func.unwrap(), key.unwrap())); + log_if_err!(self.register(key.unwrap(), func.unwrap())); } else { - log::error!(target: "app", "invalid hotkey \"{}\":\"{}\"", func.unwrap_or("None"), key.unwrap_or("None")); + log::error!(target: "app", "invalid hotkey \"{}\":\"{}\"", key.unwrap_or("None"), func.unwrap_or("None")); } } self.current = hotkeys.clone(); @@ -38,18 +39,25 @@ impl Hotkey { Ok(()) } - fn register(&mut self, func: &str, key: &str) -> Result<()> { - let hotkey = parse_hotkey(key.trim())?; + fn get_manager(&self) -> Result { + if self.manager.is_none() { + bail!("failed to get hotkey manager"); + } + Ok(self.manager.as_ref().unwrap().global_shortcut_manager()) + } - if self.manager.is_registered(&hotkey) { - self.manager.unregister(&hotkey)?; + fn register(&mut self, hotkey: &str, func: &str) -> Result<()> { + let mut manager = self.get_manager()?; + + if manager.is_registered(hotkey)? { + manager.unregister(hotkey)?; } let f = match func.trim() { "clash_mode_rule" => || feat::change_clash_mode("rule"), - "clash_mode_direct" => || feat::change_clash_mode("direct"), "clash_mode_global" => || feat::change_clash_mode("global"), - "clash_moda_script" => || feat::change_clash_mode("script"), + "clash_mode_direct" => || feat::change_clash_mode("direct"), + "clash_mode_script" => || feat::change_clash_mode("script"), "toggle_system_proxy" => || feat::toggle_system_proxy(), "enable_system_proxy" => || feat::enable_system_proxy(), "disable_system_proxy" => || feat::disable_system_proxy(), @@ -60,15 +68,14 @@ impl Hotkey { _ => bail!("invalid function \"{func}\""), }; - self.manager.register(hotkey, f)?; - log::info!(target: "app", "register hotkey {func} {key}"); + manager.register(hotkey, f)?; + log::info!(target: "app", "register hotkey {hotkey} {func}"); Ok(()) } - fn unregister(&mut self, key: &str) -> Result<()> { - let hotkey = parse_hotkey(key.trim())?; - self.manager.unregister(&hotkey)?; - log::info!(target: "app", "unregister hotkey {key}"); + fn unregister(&mut self, hotkey: &str) -> Result<()> { + self.get_manager()?.unregister(&hotkey)?; + log::info!(target: "app", "unregister hotkey {hotkey}"); Ok(()) } @@ -77,20 +84,15 @@ impl Hotkey { let old_map = Self::get_map_from_vec(¤t); let new_map = Self::get_map_from_vec(&new_hotkeys); - for diff in Self::get_diff(old_map, new_map).iter() { - match diff { - Diff::Del(key) => { - let _ = self.unregister(key); - } - Diff::Mod(key, func) => { - let _ = self.unregister(key); - log_if_err!(self.register(func, key)); - } - Diff::Add(key, func) => { - log_if_err!(self.register(func, key)); - } - } - } + let (del, add) = Self::get_diff(old_map, new_map); + + del.iter().for_each(|key| { + let _ = self.unregister(key); + }); + + add.iter().for_each(|(key, func)| { + log_if_err!(self.register(key, func)); + }); self.current = new_hotkeys; Ok(()) @@ -116,38 +118,36 @@ impl Hotkey { fn get_diff<'a>( old_map: HashMap<&'a str, &'a str>, new_map: HashMap<&'a str, &'a str>, - ) -> Vec> { - let mut list = vec![]; + ) -> (Vec<&'a str>, Vec<(&'a str, &'a str)>) { + let mut del_list = vec![]; + let mut add_list = vec![]; - old_map - .iter() - .for_each(|(key, func)| match new_map.get(key) { + old_map.iter().for_each(|(&key, func)| { + match new_map.get(key) { Some(new_func) => { if new_func != func { - list.push(Diff::Mod(key, new_func)); + del_list.push(key); + add_list.push((key, *new_func)); } } - None => list.push(Diff::Del(key)), - }); + None => del_list.push(key), + }; + }); - new_map.iter().for_each(|(key, func)| { + new_map.iter().for_each(|(&key, &func)| { if old_map.get(key).is_none() { - list.push(Diff::Add(key, func)); + add_list.push((key, func)); } }); - list + (del_list, add_list) } } impl Drop for Hotkey { fn drop(&mut self) { - let _ = self.manager.unregister_all(); + if let Ok(mut manager) = self.get_manager() { + let _ = manager.unregister_all(); + } } } - -enum Diff<'a> { - Del(&'a str), // key - Add(&'a str, &'a str), // key, func - Mod(&'a str, &'a str), // key, func -} diff --git a/src-tauri/src/core/mod.rs b/src-tauri/src/core/mod.rs index 3d122b3..21293dc 100644 --- a/src-tauri/src/core/mod.rs +++ b/src-tauri/src/core/mod.rs @@ -49,7 +49,7 @@ impl Core { Service::kill_old_clash(); let mut handle = self.handle.lock(); - handle.set_inner(app_handle); + handle.set_inner(app_handle.clone()); drop(handle); let mut service = self.service.lock(); @@ -69,7 +69,7 @@ impl Core { drop(handle); let mut hotkey = self.hotkey.lock(); - log_if_err!(hotkey.init()); + log_if_err!(hotkey.init(app_handle)); drop(hotkey); // timer initialize diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 04e266b..b5205b9 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -68,6 +68,9 @@ }, "process": { "all": true + }, + "globalShortcut": { + "all": true } }, "windows": [ diff --git a/src/components/setting/mods/hotkey-viewer.tsx b/src/components/setting/mods/hotkey-viewer.tsx index 8a66f4f..7cabed3 100644 --- a/src/components/setting/mods/hotkey-viewer.tsx +++ b/src/components/setting/mods/hotkey-viewer.tsx @@ -25,9 +25,9 @@ const ItemWrapper = styled("div")` const HOTKEY_FUNC = [ "clash_mode_rule", - "clash_mode_direct", "clash_mode_global", - "clash_moda_script", + "clash_mode_direct", + "clash_mode_script", "toggle_system_proxy", "enable_system_proxy", "disable_system_proxy",