キーボードやマウス (HID) の入力を取る

Recipe ID: hw-008

アプリがフォーカスされていない状態でもキーボードやマウスのイベントを取得したい場合(グローバルホットキーや入力監視など)、rdev クレートを使用します。

※ 単にアプリ内の入力を扱いたい場合は、JavaScript の window.addEventListener('keydown') で十分です。このレシピは OS レベルのフックについて解説します。

1. 依存関係の追加

src-tauri ディレクトリに移動して、以下のコマンドを実行します。

cargo add rdev

2. 実装(Rust 側)

rdevlisten 関数はブロッキングするため、別スレッドで実行してイベントをフロントエンドに送信します。

src-tauri/src/lib.rs

use rdev::{listen, Event, EventType};
use tauri::{AppHandle, Emitter};

#[tauri::command]
fn start_input_listener(app: AppHandle) {
    std::thread::spawn(move || {
        let callback = move |event: Event| {
            match event.event_type {
                EventType::KeyPress(key) => {
                    let _ = app.emit("input-event", format!("KeyPress: {:?}", key));
                }
                EventType::KeyRelease(key) => {
                    let _ = app.emit("input-event", format!("KeyRelease: {:?}", key));
                }
                EventType::ButtonPress(btn) => {
                    let _ = app.emit("input-event", format!("ButtonPress: {:?}", btn));
                }
                EventType::ButtonRelease(btn) => {
                    let _ = app.emit("input-event", format!("ButtonRelease: {:?}", btn));
                }
                _ => {} // MouseMove などは大量に来るので無視
            }
        };

        if let Err(error) = listen(callback) {
            eprintln!("Error: {:?}", error);
        }
    });
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![start_input_listener])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

3. 実装(フロントエンド側)

リスナーの開始とイベント受信

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

// イベントリスナーを登録
async function setupInputListener() {
  // Rust からのイベントを受信
  await listen<string>('input-event', (event) => {
    console.log('入力イベント:', event.payload);
  });

  // リスナーを開始
  await invoke('start_input_listener');
  console.log('入力監視を開始しました');
}

// 使用例
setupInputListener();

4. 注意点

  • セキュリティ: キーロガーとして振る舞うため、セキュリティソフトに誤検知される可能性があります。
  • 権限: macOS では「アクセシビリティ」権限の許可が必要です。Linux では X11/Wayland の設定依存があります(Wayland では機能しない場合が多いです)。