From ae9c33e0c72d888dd84d0ef44a15ae3032f18f6a Mon Sep 17 00:00:00 2001 From: Sami Ansari <74448287+y0usaf@users.noreply.github.com> Date: Sat, 10 Jan 2026 03:38:58 +0000 Subject: [PATCH] Fix race condition when toggling transcription via SIGUSR2 (#560) * Fix race condition when toggling transcription via SIGUSR2 The toggle state was being set to false immediately when stop was called, but the actual transcription runs asynchronously. If another signal arrived before transcription completed, a new recording could start while the old transcription was still running, causing the old text to paste unexpectedly. Now the toggle state stays true until the async transcription task completes. * remove import --------- Co-authored-by: CJ Pais --- src-tauri/src/actions.rs | 6 ++++++ src-tauri/src/signal_handle.rs | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src-tauri/src/actions.rs b/src-tauri/src/actions.rs index 602de2e..8232ded 100644 --- a/src-tauri/src/actions.rs +++ b/src-tauri/src/actions.rs @@ -8,6 +8,7 @@ use crate::settings::{get_settings, AppSettings, APPLE_INTELLIGENCE_PROVIDER_ID} use crate::shortcut; use crate::tray::{change_tray_icon, TrayIconState}; use crate::utils::{self, show_recording_overlay, show_transcribing_overlay}; +use crate::ManagedToggleState; use ferrous_opencc::{config::BuiltinConfig, OpenCC}; use log::{debug, error}; use once_cell::sync::Lazy; @@ -408,6 +409,11 @@ impl ShortcutAction for TranscribeAction { utils::hide_recording_overlay(&ah); change_tray_icon(&ah, TrayIconState::Idle); } + + // Clear toggle state now that transcription is complete + if let Ok(mut states) = ah.state::().lock() { + states.active_toggles.insert(binding_id, false); + } }); debug!( diff --git a/src-tauri/src/signal_handle.rs b/src-tauri/src/signal_handle.rs index ff4ad2d..f09a616 100644 --- a/src-tauri/src/signal_handle.rs +++ b/src-tauri/src/signal_handle.rs @@ -47,7 +47,9 @@ pub fn setup_signal_handler(app_handle: AppHandle, mut signals: Signals) { .or_insert(false); should_start = !*is_currently_active; - *is_currently_active = should_start; + if should_start { + *is_currently_active = true; + } } // Lock released here // Now call the action without holding the lock