如何让Tauri应用在macOS托盘图标上居中显示
解决Tauri macOS窗口相对于托盘图标居中显示的问题
核心思路
要实现窗口固定在屏幕顶部且相对于托盘图标居中,核心是获取托盘图标的屏幕坐标,结合窗口自身尺寸计算居中位置,最后通过window.set_position()完成定位。
步骤1:通过原生API获取托盘图标位置(Rust层)
Tauri未直接提供获取托盘图标位置的API,需调用macOS的AppKit原生接口实现。在src-tauri/src/main.rs中添加以下代码:
#[cfg(target_os = "macos")] use objc::{class, msg_send, sel, sel_impl}; #[cfg(target_os = "macos")] use cocoa::base::{id, nil}; #[cfg(target_os = "macos")] use cocoa::foundation::{NSRect, NSPoint}; #[cfg(target_os = "macos")] fn get_tray_icon_position() -> Option<(f64, f64)> { // 获取系统状态栏实例 let status_bar = unsafe { msg_send![class!(NSStatusBar), systemStatusBar] }; // 替换为你的Tauri托盘对应的NSStatusItem实例 // 若使用tauri-plugin-system-tray,可通过插件handle获取原生实例 let status_item = unsafe { msg_send![status_bar, statusItemWithLength: -1.0] }; if status_item == nil { return None; } let view = unsafe { msg_send![status_item, view] }; let frame = unsafe { msg_send![view, frame] } as NSRect; let main_screen = unsafe { msg_send![class!(NSScreen), mainScreen] }; let screen_frame = unsafe { msg_send![main_screen, frame] } as NSRect; // 转换macOS坐标系(Y轴原点在屏幕左下角,菜单栏在顶部) let center_x = frame.origin.x + frame.size.width / 2.0; let center_y = screen_frame.size.height - frame.origin.y - frame.size.height / 2.0; Some((center_x, center_y)) }
步骤2:计算窗口居中位置并绑定托盘点击事件
在App初始化的setup逻辑中,监听托盘点击事件,动态计算并设置窗口位置:
use tauri::{Window, Manager, Position, PhysicalPosition}; fn setup(app: &mut tauri::App) -> Result<(), Box<dyn std::error::Error>> { let main_window = app.get_window("main").unwrap(); let tray_handle = app.tray_handle(); // 绑定托盘点击的窗口切换逻辑 tray_handle.on_menu_event(|event| { if event.menu_item_id() == "toggle_window" { let window = event.window().unwrap(); let is_visible = window.is_visible().unwrap(); if is_visible { window.hide().unwrap(); } else { #[cfg(target_os = "macos")] if let Some((tray_x, tray_y)) = get_tray_icon_position() { let window_size = window.inner_size().unwrap(); // 计算窗口居中X坐标:托盘中心X - 窗口宽度/2 let target_x = tray_x - window_size.width as f64 / 2.0; // 窗口固定在托盘下方,添加10px偏移避免重叠 let target_y = tray_y + 10.0; window.set_position(Position::Physical(PhysicalPosition { x: target_x as i32, y: target_y as i32, })).unwrap(); } window.show().unwrap(); window.set_focus().unwrap(); } } }); Ok(()) }
步骤3:配置窗口基础属性
在tauri.conf.json中设置窗口为无边框、置顶,符合需求样式:
{ "tauri": { "windows": [ { "title": "Your App", "width": 300, "height": 400, "decorations": false, "alwaysOnTop": true, "skipTaskbar": true } ] } }
关键注意事项
- macOS坐标系特殊,Y轴原点在屏幕左下角,计算时需用屏幕总高度减去托盘的Y坐标完成转换。
- 若其他应用增减托盘项导致图标位置变化,可通过AppKit的
NSStatusBar监听状态栏变化事件,重新计算窗口位置。 - 使用
tauri-plugin-system-tray时,需确保插件版本兼容,通过插件的handle正确获取原生NSStatusItem实例。
内容的提问来源于stack exchange,提问作者Boguz
相关产品推荐
相关产品推荐

