diff --git a/desktop/src-tauri/Cargo.lock b/desktop/src-tauri/Cargo.lock index 5524b2c..0838703 100644 --- a/desktop/src-tauri/Cargo.lock +++ b/desktop/src-tauri/Cargo.lock @@ -954,6 +954,7 @@ dependencies = [ "env_logger", "futures-util", "log", + "objc2 0.5.2", "parking_lot", "reqwest 0.12.28", "serde", diff --git a/desktop/src-tauri/Cargo.toml b/desktop/src-tauri/Cargo.toml index 3cb7dbb..c02d63c 100644 --- a/desktop/src-tauri/Cargo.toml +++ b/desktop/src-tauri/Cargo.toml @@ -28,3 +28,8 @@ reqwest = { version = "0.12", features = ["json", "multipart", "rustls-tls"], de base64 = "0.22" log = "0.4" env_logger = "0.11" + +# macOS:直接设置识别浮层 NSWindow 的集合行为(浮在全屏 App 之上)。 +# 版本对齐 tao 依赖的 objc2 0.5.x,避免重复版本。 +[target.'cfg(target_os = "macos")'.dependencies] +objc2 = "0.5" diff --git a/desktop/src-tauri/src/dictation.rs b/desktop/src-tauri/src/dictation.rs index cd36af6..7295506 100644 --- a/desktop/src-tauri/src/dictation.rs +++ b/desktop/src-tauri/src/dictation.rs @@ -312,6 +312,33 @@ fn set_tray_tooltip(app: &AppHandle, text: &str) { } } +/// 让识别浮层能浮在全屏 App 之上(macOS):给 NSWindow 追加 +/// CanJoinAllSpaces | Stationary | FullScreenAuxiliary 集合行为。 +/// 仅 alwaysOnTop 不够——全屏 App 独占 Space,普通置顶窗口不会出现在其中, +/// FullScreenAuxiliary 才让浮层作为辅助窗叠加到全屏 Space 上。 +/// 必须在主线程调用(Tauri setup 闭包即主线程),窗口创建后调用一次即可。 +#[cfg(target_os = "macos")] +pub fn configure_overlay_spaces(app: &AppHandle) { + use objc2::{msg_send, runtime::AnyObject}; + // NSWindowCollectionBehavior 位标志 + const CAN_JOIN_ALL_SPACES: usize = 1 << 0; + const STATIONARY: usize = 1 << 4; + const FULL_SCREEN_AUXILIARY: usize = 1 << 8; + if let Some(w) = app.get_webview_window(OVERLAY) { + if let Ok(ptr) = w.ns_window() { + let ns = ptr as *mut AnyObject; + unsafe { + let cur: usize = msg_send![ns, collectionBehavior]; + let next = cur | CAN_JOIN_ALL_SPACES | STATIONARY | FULL_SCREEN_AUXILIARY; + let _: () = msg_send![ns, setCollectionBehavior: next]; + } + } + } +} + +#[cfg(not(target_os = "macos"))] +pub fn configure_overlay_spaces(_app: &AppHandle) {} + fn show_overlay(app: &AppHandle) { if let Some(w) = app.get_webview_window(OVERLAY) { // 跟随光标:浮层出现在指针下方 24px,水平居中 diff --git a/desktop/src-tauri/src/lib.rs b/desktop/src-tauri/src/lib.rs index 7072c5c..9aabdf3 100644 --- a/desktop/src-tauri/src/lib.rs +++ b/desktop/src-tauri/src/lib.rs @@ -132,6 +132,8 @@ pub fn run() { if let Err(e) = app.global_shortcut().register(s.hotkey.as_str()) { log::error!("register hotkey failed: {e}"); } + // 识别浮层可浮在全屏 App 之上(终端/浏览器全屏时也能看到浮层) + dictation::configure_overlay_spaces(&handle); // 首次启动 → 引导窗(11F);之后均静默启动(仅托盘常驻) if !s.onboarding_done { if let Some(w) = app.get_webview_window("onboarding") {