2019年05月06日

【QMK】カタナ式実装ではまったいくつかのポイント

QMK素人で、しかも配列を実装しようとする人が何人いるかわからないが、
僕のはまったポイントを解説することで、後進の益としたい。


1TAPとHOLDと、単押しと押しながらの制御
2レイヤー切り替えのLT()が意外と貧弱だった
3マクロ実装時にX_を使うやつ
4全角記号の実装の困難さ

の当たりを書いておくことにする。


1TAPとHOLDと、単押しと押しながらの制御

配列の常識であるのが、
単打、押しながらのシフト(通常シフト)、前置シフト、同時シフトだ。

TAPが単打、HOLDが通常シフトと勘違いしがちで、
それがはまりポイントの1だった。

TAPPING_TERMというデフォルト値200ミリ秒があり、
それ以内に押して離すとTAP、
それ以上押すとHOLD扱いになる、
ということを発見するまでに時間がかかってしまった。

これは我々の配列設計にない打ち方だ。
(それを使った配列もあるもしれないが、寡聞にして知らない。
そもそも配列変更は高速化、楽化が目的だから、
遅くなりそうなこの方式の採用はないだろう。
一方、この仕組みはキー数を減らす目的としては良さそうだ)

通常シフトを実装しようとすると、
200ミリ秒以上押してから他のを押せば意図通りのシフトになるが、
速い打鍵だと取りこぼすことになる。
単純に、QMKが取りこぼしているのか、自分の打鍵がミスしたのか、
それとも半田付けが悪かったのか(チャタリング起こしたり、抜けたり)、
原因がわからずに時間がかかってしまった。

これは、
PERMISSIVE_HOLDを有効にすることで防げる。
HOLDをTAPPING_TERM以内に他のキーが押されても有効にする、
という通常シフトのためのオプションである。

また、押して離したときに、TAPの単打が出たいときがある。
デフォルトでは、
TAPのキーを押して、TAPPING_TERMを過ぎたらHOLD扱いになってしまうため、
考えながら打っているとき、単打が出なくて困るときがあった。
(たとえばカタナ式ではスペースをSandSにしているため、
スペースをゆっくり押して変換したいときもある)
これはRETRO_TAPPINGを有効にすることで可能になる。

やり方は、config.hに、
#define PERMISSIVE_HOLD
#define RETRO_TAPPING
の二行を追加するだけでよい。
シフトキーが押して離してもなにも出ない場合、
たとえば月配列などの実装では、RETROはオンにしなくてもいいだろう。



2レイヤー切り替えのLT()が意外と貧弱だった

いろいろなドキュメントにLTの仕様が分散していて、
把握するまでに時間がかかってしまった。
LT(layer, key)は、
TAPでkey、HOLDでlayer、という、
一見我々の要求にこたえるシフト機構の実現のための道具のように思えるが、
以外とハマリがある。

1. layerは、0から15までしか対応していない
2. keyは、KCではじまる単キーにしか対応していなく、マクロに対応していない

1はレイヤー構造が複雑でない配列なら気づかないかも知れない。
カタナ式は意外と編集モードとか色々あったので、
レイヤー構成がふくらんでしまい、すぐに一杯になってしまった。
(子音ふたつで促音になるやつをレイヤーで組んだので、
それが全子音に対してレイヤーがあるので、すぐに数的爆発してしまった)
しかもコンパイル時に警告してくれないので、
「なんでレイヤーに行かないんや……」と延々調べることになってしまった。

PERMISSIVE_HOLDとRETRO_TAPPINGの問題もまだ把握していない状態だったので、
ますます混乱が生じていたのを覚えている。


2に関しては、
単打がキーのみにしか対応していない記述を見つけるのに時間がかかってしまった。
たとえばマックとウィンドウズでは編集コマンドが異なるので、
マクロで変数で使い分けよう、などと考えて、
LT(layer, MC_)
などのように組んだ(MC_はマクロのコードとした)が、
それを単打したらAltが立ち上がったり、Winキー単押しが立ち上がったり、
いきなりバグったので混乱した。
コンパイル時に警告が出ないので、まったく意味不明。
これを解決するのに、だいぶ調べたと思う。
すべてのリーチできるドキュメントに、
このふたつの説明は反映させておいてほしいよ……


3マクロ実装時にX_を使うやつ

SS_TAP()などに使うキーコードは、KC_ではじまる部分を、
X_に変更しなければならないのだが、
それがエイリアスを使っていないキーコードにしなければならない。
たとえばKC_BSPCはエイリアスで、本名はKC_BSPACEなので、X_BSPACEのようにしないといけない。
いちいち調べるのが面倒だった。

また、Winの無変換と変換、Macの英数とかなは、
それぞれ、
KC_INT5 KC_INT4(エイリアスはKC_MHEN KC_HENK)
KC_LANG2 KC_LANG1
なので、ご注意を。

(エイリアスを含んでX_を有効にするインクルードファイルがあるのかもしれないが、
あるかないかをどう探したらいいのかわからないし、
それを探すのと個別のキーコード探すのでは、
後者のほうがまだましだった)


4全角記号の実装の困難さ

Unicodeの部分で全角記号を出力しようと思ったが、
どうにもうまくいかなかった。
OSなどで変わるからかもなあ、と思ったが、
OSに左右されないキーコードとして Unicodeってあるんじゃなかったっけ、って理不尽。
そもそもSEND_STRINGで送っているのは、文字列ではなく、
キーコードでしかない、
という説明をDiscordで受けて納得した。
絵文字キーボードを実装している人を見つけたが、
そもそもOSで使用が固定されるので、
「どれにつないでも同じ機能になる」という理想が崩れるため、
結局断念した。
それぞれのマシンで、「しろまる」で「〇」を単語登録すれば出る、
というように単語登録に逃げ、キーボード側からは、
SEND_STRING("siromaru" SS_TAP(X_SPACE) SS_TAP(X_ENTER));
などのようなコードを吐くことで実現させている。

ちなみに、
SEND_STRING(SS_TAP(X_(0x30FB)));
SEND_STRING(SS_TAP(X_UC(0x30FB)));
SEND_STRING(SS_TAP(UC(0x30FB)));
SEND_STRING(UC(0x30fb));
send_unicode_hex_string("30FB");
などはすべてだめだったので、
なぜ駄目か分る人がいれば解説してほしい。


プログラマーの方から見たら、
そんなところでハマるのか、と思われるかもしれないが、
僕は非プログラマーであることを容赦されたい。
学生時代にcで簡単なものを組んだことはあるが、
それから20年後のcであったことよ。


こういう苦労を経ると、
DvorakJはとても配列作者にやさしい、
配列をいじるためだけの道具なんだなあ、
と感心してしまう。

ということで、カタナ式のQMKはオープンなので、
わからないことがあったら質問してください。
僕のわかる範囲内なら答えられます。
posted by おおおかとしひこ at 16:32| Comment(0) | カタナ式 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

※ブログオーナーが承認したコメントのみ表示されます。