右クリック時などに表示されるコンテキストメニュー(ポップアップメニュー)を実装する方法を解説します。
Tauri v2 では、作成したメニューインスタンスの popup() メソッドを呼び出すことで、任意の位置にメニューを表示できます。
1. フロントエンドから表示する (TypeScript)
contextmenu イベントをリッスンし、preventDefault() でブラウザ標準のメニューを無効化した上で、menu.popup() を呼び出します。
サンプルコード
import { Menu } from '@tauri-apps/api/menu';
// 1. ポップアップ用メニューの作成
const menu = await Menu.new({
items: [
{
id: 'reload',
text: '再読み込み',
accelerator: 'CmdOrCtrl+R', // ショートカットキー
action: () => window.location.reload()
},
{ item: 'Separator', text: '-' },
{
id: 'copy',
text: 'コピー (Custom)',
action: () => console.log('Copy clicked')
},
{ item: 'Separator', text: '-' },
{
id: 'close',
text: '閉じる',
action: () => console.log('Close clicked')
}
]
});
// 2. 右クリックイベント (contextmenu) のハンドリング
document.addEventListener('contextmenu', async (e) => {
// ブラウザ標準の右クリックメニューを抑制
e.preventDefault();
// 作成したメニューをカーソル位置にポップアップ表示
await menu.popup();
});
2. バックエンドから表示する (Rust)
Rust 側で popup を呼び出す場合は、Window インスタンス(または WebviewWindow)が必要です。
サンプルコード
use tauri::menu::{ContextMenu, MenuBuilder, MenuItemBuilder};
use tauri::WebviewWindow;
// 1. コンテキストメニューを表示するコマンド
#[tauri::command]
fn show_context_menu(window: WebviewWindow) {
// ショートカット付きのアイテムを作成
let reload = MenuItemBuilder::new("再読み込み")
.id("reload")
.accelerator("CmdOrCtrl+R")
.build(&window)
.unwrap();
let menu = MenuBuilder::new(&window)
.item(&reload)
.separator()
.text("copy", "コピー (Custom)")
.separator()
.text("close", "閉じる")
.build()
.unwrap();
// popup() は Window<R> を引数に取ります
// WebviewWindow から Window インスタンスを取得・複製して渡します
menu.popup(window.as_ref().window().clone()).unwrap();
}
// 2. イベントハンドリング (lib.rs / main.rs)
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![show_context_menu])
.on_menu_event(|app, event| {
// メニュー項目の ID に基づいて処理を分岐
match event.id().0.as_str() {
"reload" => {
println!("Reload clicked");
// 実際にリロードする場合の例:
// if let Some(window) = app.get_webview_window("main") {
// let _ = window.eval("window.location.reload()");
// }
}
"copy" => {
println!("Copy clicked");
}
"close" => {
println!("Close clicked");
}
_ => {}
}
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
補足
* 表示位置: popup() メソッドは、デフォルトで現在のマウスカーソル位置に表示されます。オプションで座標を指定することも可能です。
* 非同期: popup() は非同期関数です。await することでメニューが閉じられるまで待機するわけではありません(表示完了を待ちます)。