「編集」メニューの切り取り・コピー・貼り付け・すべて選択や、「最小化」「終了」「このアプリについて」のように、動作があらかじめ用意されている項目は標準項目(PredefinedMenuItem)で入れます。クリック時の処理を書かなくても、フォーカスのある入力欄に対するコピーなど決まった動作をします。注意点は、自前のメニューを設定すると既定のメニューが丸ごと置き換わることと、OS ごとに使えない項目があることです。メニューの組み立て方は アプリケーションのメニューバーを作る を参照してください。
前提条件
プラグインは不要です。標準項目の作成や Menu.default()(core:menu:allow-create-default)に使う権限は core:menu:default にあり、core:default に含まれるので追加は要りません。
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
"core:default"
]
}
Linux で切り取り・コピー・貼り付け・すべて選択を動かすには、src-tauri/Cargo.toml で tauri に linux-libxdo feature を足します(既存の features があればそこに追加)。必要な libxdo-dev(Fedora は libxdo-devel)は Tauri の前提パッケージに含まれています。
[dependencies]
tauri = { version = "2", features = ["linux-libxdo"] }
使える標準項目と、非対応の OS は次のとおりです(JS の item の値 / Rust のビルダーのメソッド)。
| JS / Rust | 内容 | 非対応 |
|---|---|---|
Cut Copy Paste SelectAll / .cut() .copy() .paste() .select_all() | 切り取り・コピー・貼り付け・すべて選択 | なし(Linux は linux-libxdo が必要) |
Undo Redo / .undo() .redo() | 元に戻す・やり直し | Windows・Linux |
Minimize Maximize CloseWindow / .minimize() .maximize() .close_window() | 最小化・最大化・ウィンドウを閉じる | Linux |
Quit / .quit() | アプリを終了 | Linux |
Hide HideOthers / .hide() .hide_others() | アプリを隠す・ほかを隠す | Linux |
Fullscreen ShowAll Services BringAllToFront / .fullscreen() など | フルスクリーン・すべてを表示など macOS 向け | Windows・Linux |
{ About: {...} } / .about() | このアプリについて | なし |
Separator / .separator() | 区切り線 | なし |
1. フロントエンドから実装する (TypeScript)
標準項目で「編集」メニューを組む
オブジェクト形式で item に種類を書くと標準項目になり、text で表記を変えられます。macOS では最初のサブメニューがアプリ名のメニューになるので、「このアプリについて」と「終了」を入れたサブメニューを先頭に置きます。
import { Menu, Submenu } from '@tauri-apps/api/menu';
const appMenu = await Submenu.new({
text: 'アプリ',
items: [
{ item: { About: { name: 'My Editor', version: '1.0.0', copyright: '© 2026 Example' } }, text: 'My Editor について' },
{ item: 'Separator' },
{ item: 'Quit', text: '終了' },
],
});
const editMenu = await Submenu.new({
text: '編集',
items: [
{ item: 'Undo', text: '元に戻す' }, // Windows・Linux では非対応
{ item: 'Redo', text: 'やり直し' },
{ item: 'Separator' },
{ item: 'Cut', text: '切り取り' },
{ item: 'Copy', text: 'コピー' },
{ item: 'Paste', text: '貼り付け' },
{ item: 'SelectAll', text: 'すべて選択' },
],
});
const menu = await Menu.new({ items: [appMenu, editMenu] });
await menu.setAsAppMenu();
既定のメニューを土台にする
Menu.default() は、Tauri が macOS で自動的に付けているのと同じ既定のメニュー(編集・ウィンドウ・ヘルプなど)を作ります。自分のサブメニューを append() で足せば、標準項目を 1 つずつ書かずに済みます。ただしサブメニュー名は「Edit」「Window」「Help」などの英語で固定です。
import { Menu, Submenu } from '@tauri-apps/api/menu';
const menu = await Menu.default();
await menu.append(
await Submenu.new({
text: 'ツール',
items: [{ id: 'tools-format', text: '整形', action: () => console.log('format') }],
}),
);
await menu.setAsAppMenu();
2. バックエンドから実装する (Rust)
MenuBuilder と SubmenuBuilder には標準項目ごとのメソッドがあり、.copy() は既定の表記、.copy_with_text("コピー") は指定した表記で追加します。OS で項目を変えるときは cfg!() で分岐すると、どの OS でも両方の分岐がコンパイルされるので書き間違いに気付けます。
use tauri::menu::{AboutMetadata, Menu, MenuBuilder, SubmenuBuilder};
use tauri::{AppHandle, Wry};
fn build_menu(app: &AppHandle) -> tauri::Result<Menu<Wry>> {
let info = app.package_info();
let about = AboutMetadata {
name: Some(info.name.clone()),
version: Some(info.version.to_string()),
copyright: Some("© 2026 Example".into()),
..Default::default()
};
// macOS は最初のサブメニューがアプリ名のメニューになるので、置く項目を分ける
let first = if cfg!(target_os = "macos") {
SubmenuBuilder::new(app, &info.name)
.about_with_text(format!("{} について", info.name), Some(about))
.separator()
.services_with_text("サービス")
.separator()
.hide_with_text("隠す")
.hide_others_with_text("ほかを隠す")
.separator()
.quit_with_text("終了")
.build()?
} else {
SubmenuBuilder::new(app, "ファイル")
.about_with_text("バージョン情報", Some(about))
.separator()
.close_window_with_text("閉じる") // この 2 つは Linux では非対応
.quit_with_text("終了")
.build()?
};
let edit = SubmenuBuilder::new(app, "編集")
.undo_with_text("元に戻す")
.redo_with_text("やり直し")
.separator()
.cut_with_text("切り取り")
.copy_with_text("コピー")
.paste_with_text("貼り付け")
.select_all_with_text("すべて選択")
.build()?;
MenuBuilder::new(app).item(&first).item(&edit).build()
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.menu(build_menu) // アプリ全体のメニューとして設定する
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
標準項目には action を指定できません。自前の項目(「整形」など)の処理は メニューがクリックされた時の処理を書く を参照してください。
動作確認
ページに <textarea> を置いて npm run tauri dev で起動します。文字を選択して「編集」→「コピー」、別の場所で「編集」→「貼り付け」を選ぶと貼り付けられます。Windows で「元に戻す」「やり直し」が機能しないのは非対応のためです。About の項目を選ぶと、名前・バージョン・著作権表示が表示されます。
よくあるエラーと対処法
- 自前のメニューに変えたら、macOS でコピー・貼り付けのショートカットが効かなくなった: 既定のメニューが置き換わり、編集メニューの項目ごとショートカットがなくなっています。「編集」サブメニューに
Cut・Copy・Paste・SelectAll(必要ならUndo・Redo)を入れます。 - Linux でメニューの「コピー」などを選んでも何も起きない:
linux-libxdofeature を足していません。Cargo.tomlに追加して再ビルドします。 - 標準項目を無効にしたい、クリックを拾いたい: 標準項目で変えられるのは文言だけで、
actionもsetEnabled()もありません。自前のMenuItemにして、実行中にメニュー項目を変更する(無効化・文言の書き換え) の方法で切り替えます。 - macOS で先頭に置いた「編集」がアプリ名のメニューになる: 最初のサブメニューは名前に関係なくアプリ名のメニューの位置に置かれます。アプリ用のサブメニューを先頭に置きます(Windows と macOS でメニューを出し分ける)。
- 「menu.create_default not allowed. Permissions associated with this command: core:menu:allow-create-default, core:menu:default」: capability に
core:defaultが無いときのデバッグビルドのエラーです(リリースビルドでは「Command plugin:menu|create_default not allowed by ACL」)。core:menu:defaultを足します。
OS ごとの違いと注意点
- macOS: メニューを何も設定しなければ、Tauri が既定のメニュー(
Menu.default()と同じもの)を自動で付けます。不要ならBuilder::enable_macos_default_menu(false)で止めます。Aboutのauthors・comments・license・websiteは表示されません。 - Windows: Linux と同じく、メニューを設定しなければメニューバーは付きません。
Undo・Redo・Fullscreenなどは非対応です。Aboutのiconとcreditsは使われません。 - Linux: 非対応の項目が最も多く、
Quitも使えません。終了は自前の項目を作ってクリック時にapp.exit(0)を呼ぶと、どの OS でも同じに動きます。creditsも使われません。 - 共通: 同じ標準項目は 右クリックメニュー にも入れられます。
