前々から書こう書こうって思ってましたが、やっと重い腰を上げました。
結構前からやっていたものの、そもそもglidepointが使えなかったので日の目を見なかったやつです。
html: <!–more–>
元々のfirmware
cirque pinnacleについては、元々zmkfirmwareの主要開発者が作成しているものがあります。
https://github.com/petejohanson/cirque-input-module
最初はこれを利用していたのですが、色々と機能を追加したくなってきたため、forkしています。
https://github.com/derui/cirque-input-module
改造したこと
まず、absolute modeを有効にしたかったので、このPRを取り込みました。なぜabsolute modeがやりたかったのか・・・?というところなのですが、Glidepointは円形のpadをしているなかで、「どういうふうにスクロールさせたら丁度いいのか」と考えたところ、大きく2つの案が出ました。
- トラックパッドよろしく二本指でスクロールする
- Windowsとかのトラックパッドにある、エッジ部分のスライドでスクロールする
この内、前者については、glidepointの基本モードである relative mode において対応できるのですが、二番目をやろうとすると、edge検出が必要なので、絶対座標が必要になります。で、今回はせっかくなのでedgeで指をくるくる回したらスクロールするようにしてみたかったのです。
エッジスクロールの実装
実装としては以下のPRになります。
https://github.com/derui/cirque-input-module/pull/1
いくつか使いづらい点などもあったので、追加で改造していますが、基本的には以下のように動作します。
- 所定の位置が最初のtouchであるかを確認する
- touchされているが、所定の位置でない場合は、次にtouchされるまで何もしない
- 所定の位置である場合、初期化
- 次にカーソルを動かしたら、 一つ前の位置との角度を取る
- 該当の角度(ラジアン)に対応する方向にスクロールのイベントを発行
と、結構シンプルな作りにしています。
加速度をベースにしたカーソル移動
Macbook/Appleのトラックパッドなど、現代のトラックパッドは基本的に加速度ベースでカーソルを移動しています。ゆーっくり指を動かしてトラックパッドを横断したときと、シュッと横断したときでは移動量が違うのがわかるかと思います。
オリジナルの実装では、シンプルに移動量がそのままわたっている形になっていましたが、ゆっくり動かそうとしても機敏すぎてつかいづらい・・・というのがありました。
加速度については、relative modeでもわかるのですが、改めて実装しています。なお、実装方針などはClaude Codeで確認しながら実装しました。こういう数式のパターンにハマりやすいのは、調べるより早いですね。
ただ、加速度ベースの移動は、いい塩梅を探すのが大変難しい・・・という難題があります。これについては継続して確認しているところではあります。Xiaoのリセット難易度が大変高いの、なんとかなりまへんかね 🤔
firmwareは怖くない(間違うと怖いけど)
最近のC言語は、古とは違って制約も少なくなり、だいぶ書きやすくなってます。zmkの場合は、複雑になりがちなポインタのポインタ・・・といったものがAPI上に登場することも少なく、だいぶ素直だと思います。zephyrから来ているマクロを把握するほうがよほど大変という・・・。
ちょっとここが・・・というのがあれば、当然オリジナルへの還元も視野に入れつつ、自分でいじってみるのも一興ではないでしょうか。