系统托盘

本地应用程序系统托盘。

设置

tauri.conf.json 中配置 systemTray 对象:


{
  "tauri": {
    "systemTray": {
      "iconPath": "icons/icon.png",
      "iconAsTemplate": true
    }
  }
}

iconAsTemplate 是一个布尔值,用于确定图像是否代表 macOS 上的模板图像

Linux 设置

在 Linux 上,您需要安装 libayatana-appindicatorlibappindicator3 软件包中的一个。Tauri 会在运行时决定使用哪个软件包,如果两个软件包都安装了,则优先使用 libayatana

默认情况下,Debian 软件包(.deb 文件)会添加 libayatana-appindicator3-1 的依赖关系。要创建以 libappindicator3 为目标的 Debian 软件包,请将 TAURI_TRAY 环境变量设为 libappindicator3

AppImage 打包程序会自动嵌入已安装的托盘库,你也可以使用 TAURI_TRAY 环境变量来手动选择托盘库。

信息

libappindicator3 未经维护,在某些发行版(如 debian11)上不存在,但 libayatana-appindicator 在旧版本上也不存在。

创建系统托盘

要创建本地系统托盘,请导入 SystemTray 类型:


use tauri::SystemTray;

初始化一个新的托盘实例:


let tray = SystemTray::new();

配置系统托盘上下文菜单

您还可以选择添加右键单击托盘图标时可见的上下文菜单。导入 SystemTrayMenuSystemTrayMenuItemCustomMenuItem 类型:


use tauri::{CustomMenuItem, SystemTrayMenu, SystemTrayMenuItem};

创建 SystemTrayMenu


// 这里的 `"quit".to_string()`定义了菜单项 id,第二个参数是菜单项标签。
let quit = CustomMenuItem::new("quit".to_string(), "Quit");
let hide = CustomMenuItem::new("hide".to_string(), "Hide");
let tray_menu = SystemTrayMenu::new()
  .add_item(quit)
  .add_native_item(SystemTrayMenuItem::Separator)
  .add_item(hide);

将托盘菜单添加到 SystemTray 实例中:


let tray = SystemTray::new().with_menu(tray_menu);

配置应用程序系统托盘

创建的 SystemTray 实例可以使用 tauri::Builder 结构上的 system_tray API 进行设置:


use tauri::{CustomMenuItem, SystemTray, SystemTrayMenu};

fn main() {
  let tray_menu = SystemTrayMenu::new(); // 在此处插入菜单项
  let system_tray = SystemTray::new()
    .with_menu(tray_menu);
  tauri::Builder::default()
    .system_tray(system_tray)
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
}

监听系统托盘事件

每个CustomMenuItem在被点击时都会触发一个事件。此外,Tauri还会发出托盘图标点击事件。使用 on_system_tray_event API 来处理它们:


use tauri::{CustomMenuItem, SystemTray, SystemTrayMenu, SystemTrayEvent};
use tauri::Manager;

fn main() {
  let tray_menu = SystemTrayMenu::new(); // 在此处插入菜单项
  tauri::Builder::default()
    .system_tray(SystemTray::new().with_menu(tray_menu))
    .on_system_tray_event(|app, event| match event {
      SystemTrayEvent::LeftClick {
        position: _,
        size: _,
        ..
      } => {
        println!("system tray received a left click");
      }
      SystemTrayEvent::RightClick {
        position: _,
        size: _,
        ..
      } => {
        println!("system tray received a right click");
      }
      SystemTrayEvent::DoubleClick {
        position: _,
        size: _,
        ..
      } => {
        println!("system tray received a double click");
      }
      SystemTrayEvent::MenuItemClick { id, .. } => {
        match id.as_str() {
          "quit" => {
            std::process::exit(0);
          }
          "hide" => {
            let window = app.get_window("main").unwrap();
            window.hide().unwrap();
          }
          _ => {}
        }
      }
      _ => {}
    })
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
}

更新系统托盘

AppHandle 结构有一个 tray_handle 方法,用于返回系统托盘的句柄,以便更新托盘图标和上下文菜单项:

更新上下文菜单项


use tauri::{CustomMenuItem, SystemTray, SystemTrayMenu, SystemTrayEvent};
use tauri::Manager;

fn main() {
  let tray_menu = SystemTrayMenu::new(); // 在此处插入菜单项
  tauri::Builder::default()
    .system_tray(SystemTray::new().with_menu(tray_menu))
    .on_system_tray_event(|app, event| match event {
      SystemTrayEvent::MenuItemClick { id, .. } => {
        // 获取点击菜单项的句柄
        // 注意,"tray_handle "可以在任何地方调用,
        // 只需在设置钩子上使用 `app.handle()` 获取一个 `AppHandle` 实例即可
        // 并将其移至另一个函数或线程
        let item_handle = app.tray_handle().get_item(&id);
        match id.as_str() {
          "hide" => {
            let window = app.get_window("main").unwrap();
            window.hide().unwrap();
            // 还可以 `set_selected`、`set_enabled` 和 `set_native_image`(仅限 macOS)。
            item_handle.set_title("Show").unwrap();
          }
          _ => {}
        }
      }
      _ => {}
    })
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
}

更新托盘图标

请注意,您需要在 Cargo.toml 的 tauri 依赖关系中添加 icon-icoicon-png 功能标志,才能使用 Icon::Raw


app.tray_handle().set_icon(tauri::Icon::Raw(include_bytes!("../path/to/myicon.ico").to_vec())).unwrap();

防止应用程序关闭

默认情况下,Tauri 会在最后一个窗口关闭时关闭应用程序。您只需调用 api.prevent_close() 即可避免这种情况。

根据需要,您可以使用以下两种方案之一:

保持后台在后台运行

如果后端需要在后台运行,可以像这样调用 api.prevent_exit()


tauri::Builder::default()
  .build(tauri::generate_context!())
  .expect("error while building tauri application")
  .run(|_app_handle, event| match event {
    tauri::RunEvent::ExitRequested { api, .. } => {
      api.prevent_exit();
    }
    _ => {}
  });

保持前台在后台运行

如果需要保持前台在后台运行,可以这样实现:


tauri::Builder::default().on_window_event(|event| match event.event() {
  tauri::WindowEvent::CloseRequested { api, .. } => {
    event.window().hide().unwrap();
    api.prevent_close();
  }
  _ => {}
})
.run(tauri::generate_context!())
.expect("error while running tauri application");