tokuhirom's Blog

KeyScripten.app:マクロの未来を切り開くプログラマブルキーボードシステム

QMK で増井さんの Dynamic Macro を実装してみた のだが、Mac のレイヤーで普通にやりゃいいんじゃないかという話になったので、やってみた。

rust で実装できないかなぁと思って調べてみたところ rdev を使えば良さそうだということがわかった。が、rdev は Mac, Windows, Linux をサポートしていて抽象化レイヤーとなっていて、要件を満たせないということがわかった。

rdev を見ていると、CGEventTap というAPIがあることがわかって、これをベースにやれば良さそうだった。

CGEventTap を使うと、マウスとキーボードのイベントを取れる。CGEventCreateKeyboardEvent, CGEventCreate とかして CGEventPost すればキーボード入力イベントがポストできる。ということがわかり、これを使えば Dynamic Macro を実装できるということがわかった。

JS でコアロジックを実装してみる。

当初、 DynamicMacro部分の実装を rust でゴリゴリ書いていたのだが、ふと、組み込み言語で実装できるようにしたら DynamicMacro 以外の用途にも使えるよなぁと思いついたので実装してみた。

当初は mruby を使おうと思ったのだが、最新の mruby でちゃんと動く mruby の rust binding が、探した感じなさそうだったので諦めた。

boajs という rust の JS 実装があったので、これを採用することに。JS は書けない人がいないという点が優れている。 基本的な機能は実装されてて問題なさそう。

便利なシステムトレイとアクセシビリティ設定

KeyScriptenはシステムトレイで動作し、直感的な設定ウィンドウを通じてスクリプトの追加や設定の変更が簡単に行えます。また、アプリケーションはユーザーのキーボード入力を全て捕捉するため、Macのアクセシビリティ設定で特別な許可を与える必要があります。

↑こんな感じで設定できる。

コードは以下のような感じに書ける。シンプルでしょ。

(function () {
    const id = "com.github.tokuhirom.samples";
    let latest_flags = undefined;

    registerPlugin(
        id,
        "My great script",
        "my great script",
        function (event, config) {
            if (event.type === "flagsChanged") {
                console.log(`[${id}] flagsChanged: ${event.flags}`);
                latest_flags = event.flags;
            } else if (event.type === "keyDown") {
                console.log(`[${id}] keyDown: ${event.keycode}`);
                if (config.hotkey.matches(latest_flags, event.keycode)) {
                    console.log("Handled hotkey");
                    return false;
                }
            }
            return true; /* true means, CodeKeys should send the keycode to the application. */
        },
        [ /* configuration parameters */
            {
                "name": "hotkey",
                "type": "hotkey",
                "default": "S-M-C-t",
                "description": "Key sequence for something.",
            },
            {
                "name": "size",
                    "type": "integer",
                    "description": "Size of something.",
                    "default": "64"
            }
        ]
    )
})();

プラグインと拡張性:無限の可能性

KeyScriptenは、Toshiyuki Masui氏の「ダイナミックマクロ」の実装をバンドルしています。ダイナミックマクロについては、何もしなくてもすぐに使えます。 実装はこのへん https://github.com/tokuhirom/KeyScripten/blob/main/keyscripten-core/js/dynamic-macro.js

さらに、JavaScriptを使用したカスタムスクリプトにより、ユーザーは自分だけの独自の機能やマクロを作成できます。 https://github.com/tokuhirom/KeyScripten/blob/main/HOW_TO_WRITE_SCRIPT.md スクリプトはこのマニュアルの通りに実装すれば動きます。

まとめ

KeyScripten.appは、キーボードマクロシステムの概念を根本から再定義し、プログラミングスキルを活かして日常の作業を効率化したいMacユーザーにとって理想的なツールです。JavaScriptを駆使したこのアプリケーションは、キーボード操作のカスタマイズと自動化を新たなレベルに引き上げています。KeyScriptenの開発過程は、技術的な困難と創造性の融合を示し、RustとJavaScriptの可能性を探求する興味深い旅でした。

このアプリケーションの将来は、コミュニティの参加とフィードバックによって形作られます。KeyScripten.appは、キーボードマクロとプログラミングの世界を一つにする革新的な一歩です。

See also