グローバルショートカットを登録する

Recipe ID: rust-016

アプリが最小化されていたり、別のウィンドウがアクティブになっている状態でも、キーボード操作を検知したい場合があります(例: Ctrl+Shift+P でランチャーを呼び出す)。
これを実現するのが「グローバルショートカット」です。

Tauri v2 では tauri-plugin-global-shortcut プラグインを使用します。

前提条件

Permissions (権限) の設定

src-tauri/capabilities/default.json に以下の権限を追加します。

{
    "permissions": [
        ...,
        "global-shortcut:allow-is-registered",
        "global-shortcut:allow-register",
        "global-shortcut:allow-unregister"
    ]
}

1. プラグインの導入

src-tauri ディレクトリで以下のコマンドを実行します。

cargo add tauri-plugin-global-shortcut

2. 実装例 (lib.rs)

lib.rs でプラグインを初期化し、ショートカットが押されたときの処理を記述します。

use tauri_plugin_global_shortcut::{Code, Modifiers, ShortcutState, GlobalShortcutExt};

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .setup(|app| {
            // アプリ起動時に登録したい場合(任意)
            // この機能を使うには .with_shortcut() を使うほうが簡単です
            Ok(())
        })
        .plugin(
            tauri_plugin_global_shortcut::Builder::new()
                // アプリ起動時に登録したいショートカットを指定
                .with_shortcut("Ctrl+Shift+P").unwrap()
                .with_handler(|_app, shortcut, event| {
                    // キーが「押された(Pressed)」ときだけ反応させる(離したときは無視)
                    if event.state == ShortcutState::Pressed {
                        // ショートカットの文字列などで判定も可能です
                        if shortcut.matches(Modifiers::CONTROL | Modifiers::SHIFT, Code::KeyP) {
                            println!("Ctrl+Shift+P が押されました!");
                            
                            // 必要に応じてウィンドウを表示したり、イベントを発火したりする
                        }
                    }
                })
                .build(),
        )
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

3. ショートカットの書き方

文字列で直感的に指定できます。

  • 修飾キー: Ctrl, Alt, Shift, Super (Windowsキー/Commandキー)
  • キー: A-Z, 0-9, F1-F12, Space, Enter など

例:
- "Ctrl+S"
- "Alt+Space"
- "Super+Shift+1"

4. 動的な登録と解除

アプリの設定画面などでユーザーがショートカットを変更できるようにしたい場合、動的に登録・解除を行うことも可能です。
Tauri コマンドとして定義する例です。

#[tauri::command]
fn register_my_shortcut(app: tauri::AppHandle) {
    // 登録
    // ※ すでに登録済みの場合はエラーになることがあるため、必要なら unregister してから register する
    if let Err(e) = app.global_shortcut().register("Ctrl+D") {
        eprintln!("ショートカット登録エラー: {}", e);
    }
}

#[tauri::command]
fn unregister_my_shortcut(app: tauri::AppHandle) {
    // 解除
    let _ = app.global_shortcut().unregister("Ctrl+D");
}

注意点

  • 重複に注意: OSやすでに起動している他のアプリと同じショートカットを登録しようとすると失敗することがあります。
  • macOS: アクセシビリティ権限が必要になる場合があります。開発中は設定が必要ないことが多いですが、配布時にはユーザーへの許可申請フローが必要になることがあります。
  • UX: ユーザーの意志を無視して一般的なショートカット(Ctrl+Cなど)を奪うと、非常に使いにくいアプリになるため注意してください。