自作キーボード / QMK / etc / Ctrl + h の絶対的 Backspace

自作キーボード / QMK / etc / Ctrl + h の絶対的 Backspace

とりあえずこれをやらなければキーボードカスタムは始まらないのだが、これが QMK では結構面倒だという話

自分のC言語は知って書いたことはある程度で業務で書いたことは殆どないというレベルでほぼわかってないに等しい。 現状のプログラミング力を応用してなんとかやる

まずそもそもの概念として QMKの設定はキー対してのキー挙動をコントロールするというものであり、操作に対してキャラクターを出力するものではない。

なので、このようなコンビネーションの操作を別の挙動に割り当てるにはそのキーをマップする前の事前処理の process_record_user という関数でフックする。 ドキュメントはここ Customizing Functionality - QMK

この関数は true を返すとそのまま継続処理してマッピング処理を行い、false を設定するとマップを無視して、ここで終了させるっぽい。 つまり、この関数内で、特定のキーだけ判定しキーを出力し false を返せばヨイ。これは結構原始的な操作を記述することになる。

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    return true;
}

keycode にはどのキーの操作か、record にはどのような操作かが入るっぽい。

ではまず、ctrl が押されていることを判定して保持する。

まず雑に ctrl の押下状態をグローバルに保持する。

static bool ctrl_pressed = false;
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    return true;
}

キーを判定してその中でも操作を判定して状態格納する

static bool ctrl_pressed = false;
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    if(keycode == KC_LCTRL){
        if(record->event.pressed){
            ctrl_pressed = true;
        }else{
            ctrl_pressed = false;
        }
    }
    return true;
}

別に ctrl を押すという操作自体は普通なので true を戻して次の処理に流す

次に h のキーが来た場合に挙動を変える。このようなキー操作を変えてしまう処理の場合は、register_code 関数でやりたい処理を送り込み、 unregister_code で現状の操作をキャンセルするということが定番操作っぽいのでそれに従う。

static bool ctrl_pressed = false;
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    if(keycode == KC_LCTRL){
        if(record->event.pressed){
            ctrl_pressed = true;
        }else{
            ctrl_pressed = false;
        }
    }
    if(keycode == KC_H){
        if (record->event.pressed) {
            if(ctrl_pressed){
                // ctrl + backspace を送出したいわけでないので、一瞬 ctrl を跳ね上げる
                // 操作上は ctrl が押し込まれているので連続的には ctrl は発生している
                unregister_code(KC_LCTRL);
                register_code(KC_BSPACE);
                return false;
            }
        }
    }
    return true;
}

とりあえず動いたのだが、一旦この操作をすると Backspace が止まらなくなる挙動になってしまった。 どうやらこの register_code というのは一旦使うと、そのキーが押しっぱなしになるようで、unregister_code はそれを跳ね上げる処理となるようだ。

なのでこのように跳ね上げ処理を入れておけばいいのだろう。

static bool ctrl_pressed = false;
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    if(keycode == KC_LCTRL){
        if(record->event.pressed){
            ctrl_pressed = true;
        }else{
            ctrl_pressed = false;
        }
    }
    if(keycode == KC_H){
        if(record->event.pressed) {
            if(ctrl_pressed){
                unregister_code(KC_LCTRL);
                register_code(KC_BSPACE);
                return false;
            }
        }else{
            unregister_code(KC_BSPACE);
        }
    }
    return true;
}

h を外す同時に BS が押されている状況というのは無いのでここで問題ないはず。試してみても問題なく動作した。OK C言語も QMK もほとんど理解してないがなんとかなる。

keyboard/diy_keyboard/qmk/etc/ctrl_h_absolute_backspace.txt · 最終更新: 2021-06-30 16:13 by ore