From 8453f4ac02deb64fee52f303c636aa9b9ab03057 Mon Sep 17 00:00:00 2001 From: Thomas Ricouard Date: Fri, 23 Jan 2026 18:51:54 +0100 Subject: [PATCH] Fix microphone permission prompt --- src-tauri/src/dictation.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src-tauri/src/dictation.rs b/src-tauri/src/dictation.rs index 55300b2f4..837ff2d23 100644 --- a/src-tauri/src/dictation.rs +++ b/src-tauri/src/dictation.rs @@ -54,7 +54,7 @@ fn trigger_microphone_permission_request() -> Result<(), String> { /// Returns Ok(true) if permission was granted, Ok(false) if denied, /// or Err with a message if the request failed. #[cfg(target_os = "macos")] -async fn request_microphone_permission() -> Result { +async fn request_microphone_permission(app: &AppHandle) -> Result { let status = check_microphone_authorization()?; match status { @@ -62,8 +62,20 @@ async fn request_microphone_permission() -> Result { AVAuthorizationStatus::Denied | AVAuthorizationStatus::Restricted => Ok(false), AVAuthorizationStatus::NotDetermined | _ => { // Trigger the permission request (this shows the system dialog) - // We do this in a sync context to avoid RcBlock Send issues - trigger_microphone_permission_request()?; + // Ensure we do this on the main thread so the system dialog appears. + let (tx, rx) = oneshot::channel(); + let app_handle = app.clone(); + app_handle + .run_on_main_thread(move || { + let _ = tx.send(trigger_microphone_permission_request()); + }) + .map_err(|error| error.to_string())?; + + match rx.await { + Ok(Ok(())) => {} + Ok(Err(error)) => return Err(error), + Err(_) => return Err("Failed to request microphone permission.".to_string()), + } // Poll the authorization status until it changes from NotDetermined let mut attempts = 0; @@ -84,7 +96,7 @@ async fn request_microphone_permission() -> Result { } #[cfg(not(target_os = "macos"))] -async fn request_microphone_permission() -> Result { +async fn request_microphone_permission(_app: &AppHandle) -> Result { // On non-macOS platforms, assume permission is granted // (Linux doesn't have the same permission model) Ok(true) @@ -750,7 +762,7 @@ pub(crate) async fn dictation_start( } // Request microphone permission before attempting to capture audio - match request_microphone_permission().await { + match request_microphone_permission(&app).await { Ok(true) => { // Permission granted, continue }