QMK で slave 側でも process_record() を発火する

1 min read読了の目安(約1600字

左右分離型キーボードでは、キー押下イベントのハンドリングに使う process_record() 及びそこから派生する process_record_user() 等の関数は、通常は master 側でしか実行されない。

通常はそれで問題ないが、slave 側でも OLED にキーイベントに関連した表示を行いたい場合に困った。ググっても良い情報は得られなかったので、ソースを追って調べてみた。

先に結論

  • SPLIT_TRANSPORT_MIRROR を定義
  • should_process_keypress() を override して true を返す
#define SPLIT_TRANSPORT_MIRROR

bool should_process_keypress(void) { return true; }

should_process_keypress()

process_record() を追うと、tmk_core/common/keyboard.ckeyboard_task() で発火しており、その条件として should_process_keypress() が使われていた。

またこの関数が override 可能であり、コメントを読むと今回の用途どんぴしゃだった。

/** \brief should_process_keypress
 *
 * Override this function if you have a condition where keypresses processing should change:
 *   - splits where the slave side needs to process for rgb/oled functionality
 */
__attribute__((weak)) bool should_process_keypress(void) { return is_keyboard_master();

デフォルトでは上記のように master でだけで true を返しているので、常に true を返してあげれば今回の目的の挙動になるはず。

SPLIT_TRANSPORT_MIRROR

加えて、こちらも定義する必要があった。

matrix scan されたキーの押下状態は、通常は slave から master の方向にのみ TRRS ケーブルを介して送信される。slave 側で両手分のイベントを把握するためには逆方向の情報伝達が必要で、それを実現するのがこのオプション。

https://docs.qmk.fm/#/feature_split_keyboard?id=communication-options

ドキュメントによると matrix scan のパフォーマンスに多少影響が出るようなことが書いてあったが、やってみた感じ特に体感では影響は出ていない。まあそんなにタイピング速くないので。

うまく行かないところ

この二つでほとんどうまく動いたが、slave 側で read_layer_state() の結果がおかしいという現象が見られた。本来のレイヤーキーを押しても反映されず、別のキーに反応してしまう。

が、今回の個人的な目的は達したので深追いせずここで終了。