トレイアイコンのメニューを作る

Recipe ID: menu-010

システムトレイアイコンをクリックした際に表示されるメニュー(コンテキストメニュー)を作成する方法を解説します。

Tauri v2 では、tauri::tray モジュールを使用してメニューをトレイに関連付けます。

前提条件

※ アイコン画像のロード形式に合わせて image-pngimage-ico が必要になる場合があります。

Cargo.toml の設定

Tauri v2 ではトレイ機能は Core (本体) に統合されているため、追加のプラグイン(tauri-plugin-tray など)のインストールは不要です。
ただし、src-tauri/Cargo.tomltray-icon 機能を有効にする必要があります。

[dependencies]
tauri = { version = "2", features = ["tray-icon", "image-png"] }

Permissions (権限) の設定

src-tauri/capabilities/default.jsoncore:tray:default を追加します。

{
  "permissions": [
    ...,
    "core:tray:default",
    "core:menu:default", // メニューを表示する場合
    "core:app:allow-default-window-icon" // defaultWindowIcon を使用する場合
  ]
}

1. バックエンドから作成する (Rust) - 推奨

Rust 側で TrayIconBuilder を使用します。

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 menu = MenuBuilder::new(app)
                .text("show", "表示")
                .text("hide", "隠す")
                .separator()
                .text("quit", "終了")
                .build()?;

            // トレイアイコンの作成とメニューの紐付け
            let _tray = TrayIconBuilder::with_id("tray")
                .icon(app.default_window_icon().unwrap().clone())
                .menu(&menu)
                .show_menu_on_left_click(false) // Windows等で左クリックでメニューを出すか
                .build(app)?;

            Ok(())
        })
        .on_menu_event(|app, event| {
            match event.id().0.as_str() {
                "show" => { /* ウィンドウを表示 */ }
                "hide" => { /* ウィンドウを隠す */ }
                "quit" => app.exit(0),
                _ => {}
            }
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

2. フロントエンドから作成する (TypeScript)

TrayIcon.newmenu オプションに Menu インスタンスを渡します。

import { TrayIcon } from '@tauri-apps/api/tray';
import { Menu } from '@tauri-apps/api/menu';
import { defaultWindowIcon } from '@tauri-apps/api/app';

// 1. メニューの作成
const menu = await Menu.new({
  items: [
    {
      id: 'show',
      text: 'ウィンドウを表示',
      action: async () => { /* ... */ }
    },
    { item: 'Separator' },
    {
      id: 'quit',
      text: '終了',
      action: () => { /* ... */ }
    }
  ]
});

// 2. トレイアイコンの作成
const icon = await defaultWindowIcon();
if (icon) {
    const tray = await TrayIcon.new({
      id: 'tray',
      icon: icon,
      tooltip: 'My App',
      menu: menu
    });
}