AppHandle を使ってアプリ全体を操作する

Recipe ID: rust-008

コマンドの中で、「アプリ全体」に関わる操作をしたい場合があります。
例えば、「アプリを終了させる」「新しいウィンドウを開く」「すべてのウィンドウにイベントを送る」などです。
これらは特定のウィンドウに紐づく操作ではないため、AppHandle という特別なオブジェクトを使います。

実装例

コマンドの引数に app: tauri::AppHandle を追加するだけで利用できます。

use tauri::AppHandle;
use tauri::Emitter; // イベント発信用 (v2で変更されました)

#[tauri::command]
fn control_app(app: AppHandle) {
    // 1. アプリ全体を終了させる
    // exit(0) は正常終了を意味します
    app.exit(0);
}

#[tauri::command]
fn broadcast_message(app: AppHandle, msg: String) {
    // 2. 開いている全てのウィンドウに対してイベントを発信する
    // フロントエンド側で listen("global-event", ...) していると受け取れます
    // v1の emit_all に相当します
    let _ = app.emit("global-event", msg);
}

AppHandle の特徴

AppHandle は非常に軽量で、複製(クローン)が容易です。
また、スレッドセーフ(Thread-Safe)であるため、別のスレッドに渡しても安全に動作します。

#[tauri::command]
fn delayed_quit(app: AppHandle) {
    // AppHandle をクローンして、別スレッドに渡す
    let app_handle = app.clone();
    
    std::thread::spawn(move || {
        // 3秒待つ
        std::thread::sleep(std::time::Duration::from_secs(3));
        
        // 別スレッドから安全にアプリを終了できる
        app_handle.exit(0);
    });
}

フロントエンド側の呼び出し

import { invoke } from '@tauri-apps/api/core';

function quit() {
    invoke('control_app');
}