QMKで自作キーボードを親指シフト/薙刀式へ拡張する

この記事はキーボード #1 Advent Calendar 2019の12/09 の記事です。

adventar.org

adventar.org

2020/02/09追記

QMKで親指シフト薙刀式を実装した

今年は一体型2種類、分割3種類(modulo)の合計5種類のキーボードを設計・製作して創作欲を満たした感じですが(githubでKiCADデータを公開)、ここではハードではなくQMKの話を書きたいと思います。

もともと私はRealfourceで親指シフト入力していて、Realforce R2の長くなったスペースキーに絶望し、親指シフト用キーボードを求めて自キ沼にきました。また親指シフト以外のかな入力があることを知って、薙刀式を使い始めました。

親指シフト薙刀式のかな入力をしようと思うと、WindowsならやまぶきRやDvorakJ、MacならLacailleやKarabiner-Elementを使うのが一般的ですが、私はQMKでファームウェア内にかな入力機能を実装しました。例えばキーボードを薙刀式モードに切り替えて、Fキーを押すと、キーボードからPCには'ka'の2文字が出力されて、画面に「か」と表示されます。ソフトのインストール不要なので、PC/Macに加えてiPadなどでも特殊なかな入力ができます。

githubにcrkbd用の親指シフト薙刀式のQMKファームウェアを公開しています。自分のキーボードで使ってみたい、他のかな配列へ改造してみたいという人のために、この記事でその手順を説明したいと思います。keymap.cの編集に慣れている人が対象です。

QMK親指シフト

QMK薙刀式

Crkbd以外の他のキーボードへの移植

まず薙刀式をQMKが動作するキーボードへ移植する方法です。薙刀式を例に説明しますが、親指シフトでも同様です。コアとなるnaginata.cとnaginata.hはそのまま使えるはずですので、自分のキーマップのあるフォルダにコピーします。親指シフトの場合は、nicola.cとnicola.hと読み替えてください。

修正する箇所を説明していきます。基本的には// 薙刀式で囲まれた部分を自分のconfig.h、keymap.c、rules.mkに追加していきます。


https://github.com/eswai/qmk_firmware/blob/a6be3aa8a7fdc95728bf3b637ef4e9fa9f453d9f/keyboards/crkbd/keymaps/naginata/rules.mk#L32

naginata.cがコンパイル対象になるようにrules.mkにSRC +=naginata.cを追加します。 また編集モードを使うにはUNICODE_ENABLEIMEオンオフのためにCOMBO_ENABLEも有効にしてください(親指シフトでは不要)。


https://github.com/eswai/qmk_firmware/blob/a6be3aa8a7fdc95728bf3b637ef4e9fa9f453d9f/keyboards/crkbd/keymaps/naginata/config.h#L25

config.h の// 薙刀式で囲まれた部分を自分のconfig.cに追加します。 WinとMacでは編集モードで出力するモディファイヤーキーが違うのでNAGINATA_EDIT_WINNAGINATA_EDIT_MACのどちらかを選択してください(親指シフトでは不要)。


ここからはkeymap.cを編集していきます。同様にconfig.hの// 薙刀式で囲まれた部分を適切な位置にコピペしていきますが、自分のキーボードに合わせた編集が必要です。

https://github.com/eswai/qmk_firmware/blob/a6be3aa8a7fdc95728bf3b637ef4e9fa9f453d9f/keyboards/crkbd/keymaps/naginata/keymap.c#L30

ヘッダをインクルードして薙刀式のキーレイアウトを定義するキーを導入します。


https://github.com/eswai/qmk_firmware/blob/a6be3aa8a7fdc95728bf3b637ef4e9fa9f453d9f/keyboards/crkbd/keymaps/naginata/keymap.c#L105

薙刀式用のキーを追加したので、独自のキーはSAFE_RANGEではなくNG_SAFE_RANGEから開始してください。


https://github.com/eswai/qmk_firmware/blob/a6be3aa8a7fdc95728bf3b637ef4e9fa9f453d9f/keyboards/crkbd/keymaps/naginata/keymap.c#L54

薙刀式入力モードがオンの時、_NAGINATAレイヤーに切り替わります。_NAGINATAレイヤーはデフォルトレイヤーとLOWER, RAISEなどのレイヤーの間に作っておけば、かな入力中もこれらのレイヤーを使えます。


https://github.com/eswai/qmk_firmware/blob/a6be3aa8a7fdc95728bf3b637ef4e9fa9f453d9f/keyboards/crkbd/keymaps/naginata/keymap.c#L250

_NAGINATAレイヤーを定義します。通常のKC_なんとかと言うキーコードではなく、薙刀式入力で使うキーにはNG_で始まるキーコードを使います。ここではデフォルトレイヤーにかかわらず、QWERTYでキー配置を定義してください。KCコードを使えば、かなに変換されることなく入力されるので、例えばKC_SLSHNG_SLSHを同じレイヤーに置いて、記号入力とかな入力を使い分けることが可能です。


https://github.com/eswai/qmk_firmware/blob/a6be3aa8a7fdc95728bf3b637ef4e9fa9f453d9f/keyboards/crkbd/keymaps/naginata/keymap.c#L62

薙刀式はHJキーの同時押しでIMEオンにします。これはQMKのCOMBO機能を使っています。(親指シフトでは不要)


https://github.com/eswai/qmk_firmware/blob/a6be3aa8a7fdc95728bf3b637ef4e9fa9f453d9f/keyboards/crkbd/keymaps/naginata/keymap.c#L278

初期設定として、_NAGINATAレイヤーが薙刀式のためのレイヤーであることを設定します。また編集モードのためUNICODE入力の設定をします。(親指シフトでは不要)


https://github.com/eswai/qmk_firmware/blob/a6be3aa8a7fdc95728bf3b637ef4e9fa9f453d9f/keyboards/crkbd/keymaps/naginata/keymap.c#L421

キー一発でかな入力をオンオフしたければ、キーを定義してnaginata_onまたはnaginata_offを呼び出してください。なくても可。


https://github.com/eswai/qmk_firmware/blob/a6be3aa8a7fdc95728bf3b637ef4e9fa9f453d9f/keyboards/crkbd/keymaps/naginata/keymap.c#L487

薙刀式の変換処理はprocess_record_user関数で行なっています。この関数はキーが押された時と、キーを離した時に呼び出されます。ここでnaginata.c の関数を呼び出しています。process record user関数の最後に追加してください。関数がない場合は、追加してください。


以上で移植は完了です。

親指シフト薙刀式以外の他の配列への改造

薙刀式の編集モードを実現するためにコード量が増えていますが、一般的なかな入力では不要ですので、COMBOやUNICODEコメントアウトします。これでかなりコード量は減ります。

ここでは新下駄配列を例に説明します。本質的には使うキーと、カナ変換のテーブルを修正するだけで、同時押しの処理はそのまま使えます。新下駄のために修正した箇所には// 新下駄と記載しました。

Crkbdには数字キーの行がないので完全に新下駄を実装することはできません。3行分だけの単独キー入力、中指、薬指シフト入力分だけ実装してみたいと思います。あとは容易に拡張できると思います。naginata.cとnaginata.hを改造していきます。


https://github.com/eswai/qmk_firmware/blob/1332a4011e3f36ae28b2262cd0226d68490262cd/keyboards/crkbd/keymaps/shingeta/naginata.h#L63

https://github.com/eswai/qmk_firmware/blob/1332a4011e3f36ae28b2262cd0226d68490262cd/keyboards/crkbd/keymaps/shingeta/naginata.c#L70

https://github.com/eswai/qmk_firmware/blob/1332a4011e3f36ae28b2262cd0226d68490262cd/keyboards/crkbd/keymaps/shingeta/naginata.c#L127

薙刀式は30キー+シフトキー、親指シフトも基本的な入力は30キー+2つのシフトキーで入力できます。新下駄は41キーですから、まずかな入力に使うキーを増やさないといけません。キーを増やすには上のリンクの3ヶ所を修正する必要があります。


https://github.com/eswai/qmk_firmware/blob/1332a4011e3f36ae28b2262cd0226d68490262cd/keyboards/crkbd/keymaps/shingeta/naginata.h#L79

NG_SAFE_RANGEもNGキーの数に合わせて増やしてください。


https://github.com/eswai/qmk_firmware/blob/1332a4011e3f36ae28b2262cd0226d68490262cd/keyboards/crkbd/keymaps/shingeta/naginata.c#L31

https://github.com/eswai/qmk_firmware/blob/1332a4011e3f36ae28b2262cd0226d68490262cd/keyboards/crkbd/keymaps/shingeta/naginata.c#L90

https://github.com/eswai/qmk_firmware/blob/1332a4011e3f36ae28b2262cd0226d68490262cd/keyboards/crkbd/keymaps/shingeta/naginata.c#L153

同時押しの状態をkeycomb変数で保存していますが、各ビットがキーのオンオフを表しています。親指シフト薙刀式も32キー以下なので32bitで十分でしたが、新下駄は41キー使うので、64bitに変更します。


https://github.com/eswai/qmk_firmware/blob/1332a4011e3f36ae28b2262cd0226d68490262cd/keyboards/crkbd/keymaps/shingeta/naginata.c#L784

薙刀式は最大3キー同時押ししますが、新下駄は2キーですので、変換処理を2キーで開始するように変更します。


https://github.com/eswai/qmk_firmware/blob/1332a4011e3f36ae28b2262cd0226d68490262cd/keyboards/crkbd/keymaps/shingeta/keymap.c#L250

増やしたキー(NG_X1)をキーマップに追加します。


さて、ようやくかな変換テーブルを定義します。

https://github.com/eswai/qmk_firmware/blob/1332a4011e3f36ae28b2262cd0226d68490262cd/keyboards/crkbd/keymaps/shingeta/naginata.c#L178

まずはキーの単独押しの定義です。.keyに押したキーを(B_なんとか)、.kanaに出力するローマ字表記を定義します。


https://github.com/eswai/qmk_firmware/blob/1332a4011e3f36ae28b2262cd0226d68490262cd/keyboards/crkbd/keymaps/shingeta/naginata.c#L212

次は中指シフトです。これはDまたはKと他のキーの同時押しです。.keyに同時押しする2つのキーをパイプ|で区切って定義します。キーの順序は任意です。使用時もシフトキーを先に押しても後に押しても同じように機能します。

私のQMK拡張は時間に関係なく同時に押している瞬間があれば同時押しです。ゆっくり押しても同時押しになりますし、いくら速く押しても同時に押していなければ、独立した連続のキー入力と判定します。また、シフトキーは押しっぱなしでも連続入力できます。やまぶきRやLacailleの仕様と一番違うのはこの点で、私が一番好きなところです。


https://github.com/eswai/qmk_firmware/blob/1332a4011e3f36ae28b2262cd0226d68490262cd/keyboards/crkbd/keymaps/shingeta/naginata.c#L247

薬指シフトも同様です。 新下駄にある拗音や記号はこの記事では定義していません。ぜひ完成してみてください。


https://github.com/eswai/qmk_firmware/tree/master/keyboards/crkbd/keymaps/shingeta

未完成ながら実装した新下駄配列版をここに置いておきます。

私は仕事でも自宅でもQMKの薙刀式で入力していますので、実用的に使えることは確認していますが、唯一の不満としてOSとキーボードのかな/英数モードがずれることがあります。OSが入力モードを変えてしまうことがあるのですが、キーボード側はそれを検知できないので、意図した文字が出ないことがあり、もう一度かな入力キーを押してモードを合わせないといけません。かえうちは常駐ソフトでキーボードにフィードバックしてずれないようにしていますね。 対策として、入力せずに一定時間経過後はかなキーを自動的に発行し、ずれ補正をトライ中です。

最後に

この記事は、自分で設計したmoduloアーキテクチャのminiaxeクローンに薙刀式キーキャップを乗せて、QMKに実装した薙刀式で書きました。 今年はいろんなアイデアをとにかく試してみた一年でした。来年はエンドゲームに向けて完成度を上げて満足できるキーボードを作りたいなと思います。

f:id:eswai:20191208104927j:plain
今年作ったキーボード達

追記