From 3d774b8367b8a9f641340dc6215bb1c22a8131d9 Mon Sep 17 00:00:00 2001 From: CJ Pais Date: Sun, 16 Feb 2025 19:37:32 -0800 Subject: [PATCH] Fix some weird keybinding issues --- src-tauri/Cargo.lock | 99 ++++++++++++++++++++++++++++ src-tauri/Cargo.toml | 2 + src-tauri/src/lib.rs | 12 +++- src-tauri/src/managers/audio.rs | 3 +- src-tauri/src/managers/keybinding.rs | 31 +++++++-- 5 files changed, 139 insertions(+), 8 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 6e4a957..615b273 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -78,6 +78,56 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +dependencies = [ + "anstyle", + "once_cell", + "windows-sys 0.59.0", +] + [[package]] name = "anyhow" version = "1.0.95" @@ -715,6 +765,12 @@ dependencies = [ "objc", ] +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + [[package]] name = "combine" version = "4.6.7" @@ -1254,6 +1310,29 @@ dependencies = [ "syn 2.0.96", ] +[[package]] +name = "env_filter" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + [[package]] name = "epoll" version = "4.3.3" @@ -1887,6 +1966,8 @@ version = "0.1.0" dependencies = [ "anyhow", "cpal", + "env_logger", + "log", "rdev", "rig-core", "rubato", @@ -2031,6 +2112,12 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "hyper" version = "0.14.32" @@ -2391,6 +2478,12 @@ dependencies = [ "once_cell", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" version = "0.12.1" @@ -5572,6 +5665,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "uuid" version = "1.12.1" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 0307ce4..0e4720b 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -31,6 +31,8 @@ anyhow = "1.0.95" rubato = "0.16.1" samplerate = "0.2.4" rig-core = "0.8.0" +env_logger = "0.11.6" +log = "0.4.25" [target.'cfg(target_os = "macos")'.dependencies] whisper-rs = { version = "0.13.2", features = ["metal"] } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index ec22091..7b480a2 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1,5 +1,6 @@ mod managers; +use log::{info, Level}; use managers::keybinding::KeyBindingManager; use managers::transcription::TranscriptionManager; use managers::{audio::AudioRecordingManager, transcription}; @@ -10,6 +11,8 @@ use tauri_plugin_autostart::MacosLauncher; #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { + env_logger::init(); + let recording_manager = Arc::new(AudioRecordingManager::new().expect("Failed to initialize recording manager")); let transcription_manager = @@ -39,11 +42,12 @@ pub fn run() { "ctrl-meta".to_string(), vec![Key::ControlRight, Key::MetaRight], |ctx| { - println!("Ctrl+Meta pressed!"); + info!("Ctrl+Meta pressed!"); ctx.recording_manager.try_start_recording("ctrl-meta"); None }, |ctx| { + info!("release being called from ctrl-meta"); let ctx = ctx.clone(); Some(tauri::async_runtime::spawn(async move { if let Some(samples) = ctx.recording_manager.stop_recording("ctrl-meta") { @@ -61,11 +65,12 @@ pub fn run() { "shift-alt".to_string(), vec![Key::ShiftLeft, Key::Alt], |ctx| { - println!("Shift+Alt pressed!"); + info!("Shift+Alt pressed!"); ctx.recording_manager.try_start_recording("shift-alt"); None }, |ctx| { + info!("release being called from shift-alt"); let ctx = ctx.clone(); Some(tauri::async_runtime::spawn(async move { if let Some(samples) = ctx.recording_manager.stop_recording("shift-alt") { @@ -85,11 +90,12 @@ pub fn run() { "ctrl-alt-meta".to_string(), vec![Key::ControlLeft, Key::Alt, Key::MetaLeft], |ctx| { - println!("Ctrl+Alt+Meta pressed!"); + info!("Ctrl+Alt+Meta pressed!"); ctx.recording_manager.try_start_recording("ctrl-alt-meta"); None }, |ctx| { + info!("release being called from ctrl-alt-meta"); let ctx = ctx.clone(); Some(tauri::async_runtime::spawn(async move { if let Some(samples) = ctx.recording_manager.stop_recording("ctrl-alt-meta") { diff --git a/src-tauri/src/managers/audio.rs b/src-tauri/src/managers/audio.rs index 90a109d..222a046 100644 --- a/src-tauri/src/managers/audio.rs +++ b/src-tauri/src/managers/audio.rs @@ -133,6 +133,7 @@ impl AudioRecordingManager { pub fn stop_recording(&self, binding_id: &str) -> Option> { let mut state = self.state.lock().unwrap(); + println!("Stop recording called from binding {}", binding_id); match *state { RecordingState::Recording { binding_id: ref active_id, @@ -144,7 +145,7 @@ impl AudioRecordingManager { Some(buffer.drain(..).collect()) } _ => { - println!("Cannot stop recording: not recording or wrong binding"); + // println!("Cannot stop recording: not recording or wrong binding"); None } } diff --git a/src-tauri/src/managers/keybinding.rs b/src-tauri/src/managers/keybinding.rs index be7ba7d..a2c4072 100644 --- a/src-tauri/src/managers/keybinding.rs +++ b/src-tauri/src/managers/keybinding.rs @@ -44,19 +44,38 @@ impl KeyBinding { fn handle_event(&self, key: rdev::Key, is_press: bool, context: &BindingContext) -> bool { let mut pressed = self.currently_pressed.lock().unwrap(); + if is_press { + if !self.keys.contains(&key) { + return false; // Ignore keys that aren't part of this binding + } + if pressed.contains(&key) { return false; } + pressed.insert(key); if pressed.len() == self.keys.len() && pressed.is_subset(&self.keys) { let _ = (self.on_press)(context); return true; } } else { - if pressed.remove(&key) && pressed.len() == self.keys.len() - 1 { - let _ = (self.on_release)(context); - return true; + // Release event + if !self.keys.contains(&key) { + return false; + } + + if pressed.remove(&key) { + if pressed.len() == self.keys.len() - 1 { + let _ = (self.on_release)(context); + + // Clear the currently_pressed set if all keys are released + if pressed.is_empty() { + pressed.clear(); + } + + return true; + } } } false @@ -96,8 +115,12 @@ impl KeyBindingManager { pub fn handle_event(&self, event: &rdev::Event) { if let EventType::KeyPress(key) | EventType::KeyRelease(key) = event.event_type { let is_press = matches!(event.event_type, EventType::KeyPress(_)); + + // Only process the first binding that successfully handles the event for binding in &self.bindings { - binding.handle_event(key, is_press, &self.context); + if binding.handle_event(key, is_press, &self.context) { + break; // Exit after first successful handling + } } } }