diff --git a/src-tauri/src/api/hotkeys.rs b/src-tauri/src/api/hotkeys.rs index 994894b..a530b27 100644 --- a/src-tauri/src/api/hotkeys.rs +++ b/src-tauri/src/api/hotkeys.rs @@ -6,20 +6,20 @@ use global_hotkey::{ GlobalHotKeyManager, HotKeyState, }; -use lazy_static::lazy_static; use std::str::FromStr; use std::sync::Mutex; -use tauri::{ AppHandle, Listener, Manager }; +use tauri::{ AppHandle, Manager, Listener }; use tauri_plugin_aptabase::EventTracker; +use tokio::sync::OnceCell; -lazy_static! { - static ref HOTKEY_MANAGER: Mutex> = Mutex::new(None); - static ref REGISTERED_HOTKEY: Mutex> = Mutex::new(None); -} +static HOTKEY_MANAGER: OnceCell>> = OnceCell::const_new(); +static REGISTERED_HOTKEY: OnceCell>> = OnceCell::const_new(); pub fn setup(app_handle: tauri::AppHandle) { - let app_handle_clone = app_handle.clone(); + let _ = HOTKEY_MANAGER.set(Mutex::new(None)); + let _ = REGISTERED_HOTKEY.set(Mutex::new(None)); + let app_handle_clone = app_handle.clone(); let manager = match GlobalHotKeyManager::new() { Ok(manager) => manager, Err(err) => { @@ -28,8 +28,8 @@ pub fn setup(app_handle: tauri::AppHandle) { } }; - { - let mut manager_guard = HOTKEY_MANAGER.lock().unwrap(); + if let Some(hotkey_manager) = HOTKEY_MANAGER.get() { + let mut manager_guard = hotkey_manager.lock().unwrap(); *manager_guard = Some(manager); } @@ -42,19 +42,17 @@ pub fn setup(app_handle: tauri::AppHandle) { eprintln!("Error registering initial shortcut: {:?}", e); } + setup_event_listeners(&app_handle); + setup_hotkey_receiver(app_handle); +} + +fn setup_event_listeners(app_handle: &AppHandle) { app_handle.listen("update-shortcut", move |event| { let payload_str = event.payload().replace("\\\"", "\""); let trimmed_str = payload_str.trim_matches('"'); - - if let Some(old_hotkey) = REGISTERED_HOTKEY.lock().unwrap().take() { - let manager_guard = HOTKEY_MANAGER.lock().unwrap(); - if let Some(manager) = manager_guard.as_ref() { - let _ = manager.unregister(old_hotkey); - } - } - + unregister_current_hotkey(); + let payload: Vec = serde_json::from_str(trimmed_str).unwrap_or_default(); - if let Err(e) = register_shortcut(&payload) { eprintln!("Error re-registering shortcut: {:?}", e); } @@ -62,21 +60,16 @@ pub fn setup(app_handle: tauri::AppHandle) { app_handle.listen("save_keybind", move |event| { let payload_str = event.payload().to_string(); - - if let Some(old_hotkey) = REGISTERED_HOTKEY.lock().unwrap().take() { - let manager_guard = HOTKEY_MANAGER.lock().unwrap(); - if let Some(manager) = manager_guard.as_ref() { - let _ = manager.unregister(old_hotkey); - } - } - + unregister_current_hotkey(); + let payload: Vec = serde_json::from_str(&payload_str).unwrap_or_default(); if let Err(e) = register_shortcut(&payload) { eprintln!("Error registering saved shortcut: {:?}", e); } }); +} - let app_handle_for_hotkey = app_handle.clone(); +fn setup_hotkey_receiver(app_handle: AppHandle) { tauri::async_runtime::spawn(async move { loop { match GlobalHotKeyEvent::receiver().recv() { @@ -84,24 +77,40 @@ pub fn setup(app_handle: tauri::AppHandle) { if event.state == HotKeyState::Released { continue; } - handle_hotkey_event(&app_handle_for_hotkey); - } - Err(e) => { - eprintln!("Error receiving hotkey event: {:?}", e); + handle_hotkey_event(&app_handle); } + Err(e) => eprintln!("Error receiving hotkey event: {:?}", e), } } }); } +fn unregister_current_hotkey() { + if let Some(registered) = REGISTERED_HOTKEY.get() { + if let Some(old_hotkey) = registered.lock().unwrap().take() { + if let Some(manager) = HOTKEY_MANAGER.get() { + if let Some(manager) = manager.lock().unwrap().as_ref() { + let _ = manager.unregister(old_hotkey); + } + } + } + } +} + fn register_shortcut(shortcut: &[String]) -> Result<(), Box> { let hotkey = parse_hotkey(shortcut)?; - let manager_guard = HOTKEY_MANAGER.lock().unwrap(); - if let Some(manager) = manager_guard.as_ref() { - manager.register(hotkey.clone())?; - *REGISTERED_HOTKEY.lock().unwrap() = Some(hotkey); - Ok(()) + if let Some(manager) = HOTKEY_MANAGER.get() { + let manager_guard = manager.lock().unwrap(); + if let Some(manager) = manager_guard.as_ref() { + manager.register(hotkey.clone())?; + if let Some(registered) = REGISTERED_HOTKEY.get() { + *registered.lock().unwrap() = Some(hotkey); + } + Ok(()) + } else { + Err("Hotkey manager not initialized".into()) + } } else { Err("Hotkey manager not initialized".into()) } @@ -113,21 +122,11 @@ fn parse_hotkey(shortcut: &[String]) -> Result { - modifiers |= Modifiers::CONTROL; - } - "AltLeft" => { - modifiers |= Modifiers::ALT; - } - "ShiftLeft" => { - modifiers |= Modifiers::SHIFT; - } - "MetaLeft" => { - modifiers |= Modifiers::META; - } - key => { - code = Some(Code::from(KeyCode::from_str(key)?)); - } + "ControlLeft" => modifiers |= Modifiers::CONTROL, + "AltLeft" => modifiers |= Modifiers::ALT, + "ShiftLeft" => modifiers |= Modifiers::SHIFT, + "MetaLeft" => modifiers |= Modifiers::META, + key => code = Some(Code::from(KeyCode::from_str(key)?)), } } @@ -157,8 +156,8 @@ fn handle_hotkey_event(app_handle: &AppHandle) { "hotkey_triggered", Some( serde_json::json!({ - "action": if window.is_visible().unwrap() { "hide" } else { "show" } - }) + "action": if window.is_visible().unwrap() { "hide" } else { "show" } + }) ) ); -} +} \ No newline at end of file