前々から書こう書こうって思ってましたが、やっと重い腰を上げました。

結構前からやっていたものの、そもそも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

いくつか使いづらい点などもあったので、追加で改造していますが、基本的には以下のように動作します。

  1. 所定の位置が最初のtouchであるかを確認する
    1. touchされているが、所定の位置でない場合は、次にtouchされるまで何もしない
  2. 所定の位置である場合、初期化
  3. 次にカーソルを動かしたら、 一つ前の位置との角度を取る
  4. 該当の角度(ラジアン)に対応する方向にスクロールのイベントを発行

と、結構シンプルな作りにしています。

加速度をベースにしたカーソル移動

Macbook/Appleのトラックパッドなど、現代のトラックパッドは基本的に加速度ベースでカーソルを移動しています。ゆーっくり指を動かしてトラックパッドを横断したときと、シュッと横断したときでは移動量が違うのがわかるかと思います。

オリジナルの実装では、シンプルに移動量がそのままわたっている形になっていましたが、ゆっくり動かそうとしても機敏すぎてつかいづらい・・・というのがありました。

加速度については、relative modeでもわかるのですが、改めて実装しています。なお、実装方針などはClaude Codeで確認しながら実装しました。こういう数式のパターンにハマりやすいのは、調べるより早いですね。

ただ、加速度ベースの移動は、いい塩梅を探すのが大変難しい・・・という難題があります。これについては継続して確認しているところではあります。Xiaoのリセット難易度が大変高いの、なんとかなりまへんかね 🤔

firmwareは怖くない(間違うと怖いけど)

最近のC言語は、古とは違って制約も少なくなり、だいぶ書きやすくなってます。zmkの場合は、複雑になりがちなポインタのポインタ・・・といったものがAPI上に登場することも少なく、だいぶ素直だと思います。zephyrから来ているマクロを把握するほうがよほど大変という・・・。

ちょっとここが・・・というのがあれば、当然オリジナルへの還元も視野に入れつつ、自分でいじってみるのも一興ではないでしょうか。