qmk_firmware(ergodox)でAltTabを実装する方法

ergodox_ezで、 AltTab をどうやって実装すれば良いのかわからず悶々としていたのですが、ようやくわかりました。

Alt も TAB も使わず、あるいはどっちかだけ使って AltTab を実現したかったのです。

ergodoxで言うところの、「Vの下(QWERTYの場合)」、通常の日本語配列のキーボードで言えば無変換キー的な、macで言ったら英数の位置にある、あのキー。親指で押しやすくて大変便利なので徹底的に使い倒したいと思っていました。

このキーに Ctrl や Alt のような役割を担わせつつ、単打で IMEオフ もさせたい、そしてどんどん欲が出てきて AltTab も当然視野に入ってくる訳です。

なにが良いかというと、無変換キー押しっぱなしで AltTab ができれば、独自に設定する方向キー(HJKL)も流れで使えます。逆方向へ移動するときにわざわざ Shift + TAB する必要がない上に、ウィンドウを開きまくったときの上下移動もサクッとできるためとても便利で楽チンなのです。

公式のマニュアルには、「スーパーALT↯TAB」と題して、1秒経つと勝手に切れるやつが例として載っています。

高度な例: スーパー ALT↯TAB

ですが、そういうのではなくて Windows10 のような、普通の素朴な AltTab が欲しかったのです。

qmk_firmware で AltTab


// 独自に設定するキーの記述
enum custom_keycodes {
    Z_ALT = SAFE_RANGE,  // 偽Alt
    Z_TAB,  // 偽TAB
};

// 独自の関数を記述する部分

alt_pressed = false; // 偽Alt が押されたかどうかのフラグ
tab_pressed = false; // 偽TAB が押されたかどうかのフラグ
is_alttab_active = false; // AltTab 実行中のフラグ


bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    switch (keycode) {

        // 偽Alt
        case Z_ALT: 
            // 偽Alt オン。Alt が押されたことにする
            if (record->event.pressed) {
                alt_pressed = true;
                register_code(KC_LALT);

            // 偽Alt オフ。Alt が放されれば AltTab もオフになる
            } else {
                alt_pressed = false;
                if (is_alttab_active) {
                    is_alttab_active = false;
                }
                unregister_code(KC_LALT);
            }
            break;

        // 偽TAB
        case Z_TAB:
            // 偽TAB オン。TABが押されたことにする
            if (record->event.pressed) {

                // Altが押されているならば、AltTab をオンにする 
                if (alt_pressed) {
                    is_alttab_active = true;
                }
                register_code(KC_TAB);
            } else {
                unregister_code(KC_TAB);
            }
            break;
        default:
            if (record->event.pressed) {
                // reset the flags
                alt_pressed = false;
                tab_pressed = false;
            }
            break;
    }
    return true;
};

無変換に複数の役割を担わせる複雑なパターン

#include QMK_KEYBOARD_H
#include "version.h"

// レイヤーの記述
#define _BASE 0   // default layer
#define _CMD 1    // Control や alt のようなレイヤー

// 独自に設定するキーの記述
enum custom_keycodes {
    BASE = SAFE_RANGE,
    CMD,
    ALT_TAB, 
};

//////////////////////

// キーマップの部分
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {

ALT_TAB, // ← 通常は KC_TAB の位置に記述
CMD, // ← 通常は KC_MHEN の記述

};
//////////////////////


static bool cmd_pressed = false; // 無変換キーが押されているかどうかのフラグ
static uint16_t cmd_pressed_time = 0; // 無変換キーが押されてからの時間
static bool is_alttab_active = false; // AltTab のフラグ(デフォルトはオフ)

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    switch (keycode) {
        case CMD:
            // 無変換キーを押したとき
            if (record->event.pressed) {
                cmd_pressed = true; // CMD(KC_MHEN)が押されたらフラグを立てる
                cmd_pressed_time = record->event.time;
                layer_on(_CMD); // _CMDレイヤーをオン

            // 無変換キーを放したとき
            } else {
                // レイヤーをオフ
                layer_off(_CMD);

                // 単打 (普通に無変換キーが押して放される)
                if (cmd_pressed && (TIMER_DIFF_16(record->event.time, cmd_pressed_time) < TAPPING_TERM)) {
                    register_code(KC_MHEN);
                    unregister_code(KC_MHEN);

                // AltTab がオンで 無変換キーを離した場合
                } else if (is_alttab_active) { 
                    // CMD(KC_MHEN) を放せば Alt もオフになって AltTab が解除される。
                    is_alttab_active = false; 
                    unregister_code(KC_LALT);
                }
                cmd_pressed = false;
            }
            return false;
            break;

        // TABキー(_CMDレイヤーでAltTabを発動するキー)
        case ALT_TAB:
            // キーが押されたとき
            if (record->event.pressed) {
                is_alttab_active = true; // AltTabのフラグをオン
                register_code(KC_LALT); // Altを押しっぱなしにする
                register_code(KC_TAB); // TABを押す

            // キーを放したとき
            } else {
                unregister_code(KC_TAB); // TABを放す
            }
            break;

        default:
            if (record->event.pressed) {
                // reset the flags
                cmd_pressed = false;
            }
            break;
    }
    return true;
};

無変換キーや変換キーの単打を思い通りの挙動になるように調節するのはまだまだ研究が必要です。

参考: QMK Firmware で Raise/Lower と変換/無変換を同じキーに割り当てる

記事一覧へ戻る
メニュー