WindowsのキーボードにMacのようなfnキーを導入する


何がやりたい?

以下の図のようなキーバインドを Windows でも実現したい。 1

どうやって?

このような用途に使える有名なツールとしては のどかAutoHotkey などがあるが、今回はドッグフーディングも兼ねて自作ツールの Crevice で設定を行った。

Crevice の設定

// マウスジェスチャーとは別のプロファイルを作る。
DeclareProfile("Keyboard");

{
    var fn = false;

    // 常に有効なジェスチャを設定する
    var Whenever = When(ctx =>
    {
        return true;
    });

    // ここでは右シフトキーをfnキーとして設定する
    Whenever.
    OnDecomposed(Keys.RShiftKey).
    Press(ctx => fn = true).
    Release(ctx => fn = false);

    // fnキーが有効なとき、あるキーを別のキーに変更する
    void swapIfFn(
        Crevice.Core.DSL.WhenElement<Crevice.GestureMachine.EvaluationContext, Crevice.GestureMachine.ExecutionContext> when,
        Crevice.UserScript.Keys.LogicalSystemKey from,
        Crevice.UserScript.Keys.LogicalSystemKey to
    ) {
        when.
        OnDecomposed(from).
        Press(ctx => {
            if (fn) {
                SendInput.KeyDown(to);
                return;
            }
            SendInput.KeyDown(from);
        }).
        Release(ctx => {
            if (fn) {
                SendInput.KeyUp(to);
                return;
            }
            SendInput.KeyUp(from);
        });
    }   

    // fnキーが有効なとき、あるキーを無効にする
    void disableIfFn(
        Crevice.Core.DSL.WhenElement<Crevice.GestureMachine.EvaluationContext, Crevice.GestureMachine.ExecutionContext> when,
        Crevice.UserScript.Keys.LogicalSystemKey from
    ) {
        when.
        OnDecomposed(from).
        Press(ctx => {
            if (fn) {
                return;
            }
            SendInput.KeyDown(from);
        }).
        Release(ctx => {
            if (fn) {
                return;
            }
            SendInput.KeyUp(from);
        });
    }   

    // fn + 1234567890-^ -> F1-12
    swapIfFn(Whenever, Keys.D1, Keys.F1);
    swapIfFn(Whenever, Keys.D2, Keys.F2);
    swapIfFn(Whenever, Keys.D3, Keys.F3);
    swapIfFn(Whenever, Keys.D4, Keys.F4);
    swapIfFn(Whenever, Keys.D5, Keys.F5);
    swapIfFn(Whenever, Keys.D6, Keys.F6);
    swapIfFn(Whenever, Keys.D7, Keys.F7);
    swapIfFn(Whenever, Keys.D8, Keys.F8);
    swapIfFn(Whenever, Keys.D9, Keys.F9);
    swapIfFn(Whenever, Keys.D0, Keys.F10);
    swapIfFn(Whenever, Keys.OemMinus, Keys.F11);
    swapIfFn(Whenever, Keys.Oem7, Keys.F12);

    // fn + JIKL -> ←↑↓→
    swapIfFn(Whenever, Keys.J, Keys.Left);
    swapIfFn(Whenever, Keys.I, Keys.Up);
    swapIfFn(Whenever, Keys.K, Keys.Down);
    swapIfFn(Whenever, Keys.L, Keys.Right);

    // fn + UOP; -> N/A
    disableIfFn(Whenever, Keys.U);
    disableIfFn(Whenever, Keys.O);
    disableIfFn(Whenever, Keys.P);
    disableIfFn(Whenever, Keys.Oemplus);

    // fn + @ -> Home
    swapIfFn(Whenever, Keys.Oem3, Keys.Home);
    // fn + : -> End
    swapIfFn(Whenever, Keys.Oem1, Keys.End);

    // fn + [ -> PageUp
    swapIfFn(Whenever, Keys.Oem4, Keys.PageUp);
    // fn + ] -> PageDown
    swapIfFn(Whenever, Keys.Oem6, Keys.PageDown);
}

Mac のような「英数」「かな」での IME 切り替えを実現する

Google IME のキー設定で「無変換」「変換」にそれぞれ「IME を無効化」「IME を有効化」を割り当てる。

OS レベルであるキーを別のキーに割り当てる

Change Key が使いやすい。




  1. MacではKarabiner-Elementsで実現できる。参考: https://gist.github.com/rubyu/9f6b0b823df13214fb33ef507f051aab