diff --git a/openless-all/app/src-tauri/src/coordinator.rs b/openless-all/app/src-tauri/src/coordinator.rs index 56d65fcc..afc602f1 100644 --- a/openless-all/app/src-tauri/src/coordinator.rs +++ b/openless-all/app/src-tauri/src/coordinator.rs @@ -4585,9 +4585,14 @@ fn emit_capsule( match aux { Some(t) => { log::info!("[capsule] set_aux_down: {t}"); - if let Err(e) = crate::linux_fcitx::set_aux_down(t) { - log::warn!("[capsule] set_aux_down failed: {e}"); - } + // 把 DBus I/O 移到独立线程:emit_capsule 会被音频回调线程 + // (cpal) 调用,同步阻塞可能导致录音卡顿或可闻杂音。 + let text = t.to_string(); + std::thread::spawn(move || { + if let Err(e) = crate::linux_fcitx::set_aux_down(&text) { + log::warn!("[capsule] set_aux_down failed: {e}"); + } + }); // 首次设置(从 None 转为有值)时,fcitx5 可能还在处理触发 // 快捷键的按键事件(press/release),这些事件可能覆盖 auxDown。 // 延迟 300ms 重设一次确保状态不被竞态覆盖。 @@ -4610,9 +4615,12 @@ fn emit_capsule( } None => { log::info!("[capsule] clear_aux_down"); - if let Err(e) = crate::linux_fcitx::clear_aux_down() { - log::warn!("[capsule] clear_aux_down failed: {e}"); - } + // 同样从音频线程挪走,避免阻塞。 + std::thread::spawn(|| { + if let Err(e) = crate::linux_fcitx::clear_aux_down() { + log::warn!("[capsule] clear_aux_down failed: {e}"); + } + }); } } } diff --git a/openless-all/app/src-tauri/src/linux_fcitx.rs b/openless-all/app/src-tauri/src/linux_fcitx.rs index b0b51959..9dae5b09 100644 --- a/openless-all/app/src-tauri/src/linux_fcitx.rs +++ b/openless-all/app/src-tauri/src/linux_fcitx.rs @@ -475,14 +475,27 @@ pub fn ensure_plugin_installed(app: &tauri::AppHandle) { #[cfg(target_os = "linux")] fn is_plugin_installed_on_disk() -> bool { - let system_so_paths = [ - "/usr/lib/x86_64-linux-gnu/fcitx5/libopenless.so", - "/usr/lib64/fcitx5/libopenless.so", - "/usr/local/lib/fcitx5/libopenless.so", - "/usr/lib/fcitx5/libopenless.so", + // 同时检查 .so 和 .conf:孤立的 .so 没有 addon 配置 fcitx5 也不会加载。 + let pairs: &[(&str, &str)] = &[ + ( + "/usr/lib/x86_64-linux-gnu/fcitx5/libopenless.so", + "/usr/share/fcitx5/addon/openless.conf", + ), + ( + "/usr/lib64/fcitx5/libopenless.so", + "/usr/share/fcitx5/addon/openless.conf", + ), + ( + "/usr/local/lib/fcitx5/libopenless.so", + "/usr/local/share/fcitx5/addon/openless.conf", + ), + ( + "/usr/lib/fcitx5/libopenless.so", + "/usr/share/fcitx5/addon/openless.conf", + ), ]; - for path in &system_so_paths { - if std::path::Path::new(path).exists() { + for (so, conf) in pairs { + if std::path::Path::new(so).exists() && std::path::Path::new(conf).exists() { return true; } } @@ -490,7 +503,9 @@ fn is_plugin_installed_on_disk() -> bool { if let Ok(home) = std::env::var("HOME") { let user_so = std::path::PathBuf::from(&home) .join(".local").join("lib").join("fcitx5").join("libopenless.so"); - if user_so.exists() { + let user_conf = std::path::PathBuf::from(&home) + .join(".local").join("share").join("fcitx5").join("addon").join("openless.conf"); + if user_so.exists() && user_conf.exists() { return true; } }