アプリケーションをシステムトレイ(Windows のタスクトレイ、macOS のメニューバー)に常駐させる方法を解説します。
Tauri v2 では、tauri::tray モジュール(Core機能)を使用してトレイアイコンを作成・管理します。
前提条件
※ アイコン画像のロード形式に合わせて image-png や image-ico が必要になる場合があります。
Cargo.toml の設定
Tauri v2 ではトレイ機能は Core (本体) に統合されているため、追加のプラグイン(tauri-plugin-tray など)のインストールは不要です。
ただし、src-tauri/Cargo.toml で tray-icon 機能を有効にする必要があります。
[dependencies]
tauri = { version = "2", features = ["tray-icon", "image-png"] }
Permissions (権限) の設定
src-tauri/capabilities/default.json に core:tray:default を追加します。
{
"permissions": [
...,
"core:tray:default",
"core:menu:default", // メニューを表示する場合
"core:app:allow-default-window-icon" // defaultWindowIcon を使用する場合
]
}
1. バックエンドから作成する (Rust) - 推奨
Rust 側で TrayIconBuilder を使用するのが最も標準的で安定した方法です。
Rust(バックエンド)での作成が推奨される理由:
* 安定した常駐性: フロントエンド(WebView)が閉じられたりリロードされたりしても、Rust 側のプロセスは生き続けるため、トレイアイコンが消失するリスクがありません。
* ウィンドウレス起動: ウィンドウを生成しない(または非表示で起動する)常駐型アプリの場合、フロントエンドが存在しないため Rust での実装が必須となります。
* リソース管理: アイコン画像などのリソースへのアクセスや型安全性が確保しやすく、実装が堅牢になります。
use tauri::menu::{MenuBuilder, MenuItem};
use tauri::tray::TrayIconBuilder;
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.setup(|app| {
// トレイメニューの作成
let quit_i = MenuItem::with_id(app, "quit", "終了", true, None::<&str>)?;
let menu = MenuBuilder::new(app)
.item(&quit_i)
.build()?;
// トレイアイコンの作成
let _tray = TrayIconBuilder::with_id("tray")
// アプリのデフォルトアイコンを使用(tauri.conf.json由来)
.icon(app.default_window_icon().unwrap().clone())
.menu(&menu)
.show_menu_on_left_click(true) // 左クリックでもメニューを出す場合
.on_menu_event(|app, event| {
match event.id().as_ref() {
"quit" => {
println!("Quit menu item clicked");
app.exit(0);
}
_ => {}
}
})
.on_tray_icon_event(|tray, event| {
// トレイアイコンに対するクリックイベントなど
// (menuイベントとは別です)
use tauri::tray::TrayIconEvent;
if let TrayIconEvent::Click { .. } = event {
println!("Tray icon clicked");
}
})
.build(app)?;
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
2. フロントエンドから作成する (TypeScript)
システムトレイ(タスクトレイ)の常駐はバックエンドから作成する (Rust) ことが推奨されますが、フロントエンドからも作成可能です。しかし、特別な理由がない限りはバックエンドから作成する (Rust) するのが良いでしょう。
import { TrayIcon } from '@tauri-apps/api/tray';
import { Menu } from '@tauri-apps/api/menu';
import { defaultWindowIcon } from '@tauri-apps/api/app';
// トレイメニューの作成
const menu = await Menu.new({
items: [
{
id: 'quit',
text: '終了',
action: () => {
// import { exit } from '@tauri-apps/plugin-process';
// await exit(0);
console.log("Quit clicked");
}
}
]
});
// トレイアイコンの作成
const tray = await TrayIcon.new({
id: 'tray',
tooltip: 'My Tauri App',
menu: menu,
action: (event) => {
// Click, DoubleClick, etc.
console.log('Tray event', event);
}
});
// アイコンの設定 (デフォルトアイコンを使用する例)
const icon = await defaultWindowIcon();
if (icon) {
await tray.setIcon(icon);
}
補足
* 静的構成: 単純なトレイアイコンであれば、tauri.conf.json の app > trayIcon 設定を使用することも可能ですが、メニューの動的な制御などを行う場合はコードで記述する「動的構成」が推奨されます。
* マルチプラットフォーム: macOS, Windows, Linux でトレイの挙動(クリック時の動作など)が微妙に異なる場合があります。