Keyboard Quantizer をマウスに使う
Posted on Jul 28, 2021
前にも書いた気もしますが、今は、KVM スイッチャー使って、1 セットのモニター・キーボード・マウスで複数のパソコンを切り替えながらお仕事してます。
で、ずっと気になってたのが、Windows と Mac でのマウスの挙動の違い(というか、エレコム製マウス・トラックボールの Mac 用ドライバーのしょぼさ)。
もうちょっと細かく書くと、
- Windows と Mac でホイールスクロールの向きが逆。Mac の設定で向きを変えられるんだけど、変えてしまうと、内臓のトラックパッドのスクロールの向きも逆になり、外出先なんかで使ってると、イラっとする。ホイールの向きを管理するアプリなんかもあるんだけど、あんまり常駐ソフト増やしたくない。
 - エレコムのドライバーを入れないと、Mac の Safari で「戻る」「進む」が動作しなかったり、ボタン 6 ~ボタン 8 なんかも動作しないんだけれど、エレコムのドライバーが端的に言ってクソ。
 
てな感じ。
ま、作業できなくはないので、放置してたんですが、この度、せきごん氏の Keyboard Quantizer を導入して、解決できるか試してみました。
Keyboard Quantizer
Keyboard Quantizer っていうのは、キーボードやマウスのアダプターとして使うもので、このアダプター上で、キーボードなりマウスなりの入力を変換してしまいましょう、っていう製品。ユーザーがファームウェアを書き換えられないような普通のキーボードなんかでも、レイヤー機能をついかしたり、キーマップ変えたりできる、っていう代物です。
使い方はちょっと複雑でしたが、ビルドガイドにのっとり、
- Bootloader を焼く
 - ホスト用のファームウェアを焼く
 - 実際にキー改変するファームウェアを焼く
 
っていう、3つの行程を経て準備完了。
半年くらい前に買ったときには、マウス用のファームウェアなかった気がしますが、今は、サンプルが用意されています。
実際にやりたいこと
最初にちょっと書きましたが、やりたいことは、以下の3つ。
- Windows/Mac でそれぞれ別のレイヤーを作成し、ボタンでレイヤーを切り替える。
 - Mac 用のレイヤーでは、ボタン 4 ~ ボタン 8 に、「戻る(GUI + [)」、「進む(GUI + ])」、「左作業スペース(Ctrl + LEFT)」、「レイヤー切り替え」、「右作業スペース(Ctrl + RIGHT)」をそれぞれ割り振る
 - Mac 用のレイヤー時には、スクロールの向きを変える
 
ちょっと悪戦苦闘しましたが、無事実装。
1 と 2 に関しては、こんな感じで実装しています。
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    [0] = {{KC_BTN1, KC_BTN2, KC_BTN3, KC_BTN4,       KC_BTN5,       KC_NO,         TG(1),   KC_NO        }},
    [1] = {{_______, _______, _______, LGUI(KC_LBRC), LGUI(KC_RBRC), LCTL(KC_LEFT), _______, LCTL(KC_RGHT)}},
};3 に関しては、今いるレイヤーを認識したうえで、V 方向の向きを変える、ってので実装してみました。
void mouse_report_hook(mouse_parse_result_t const* report) {
    //中略
    mouse.x += report->x;
    mouse.y += report->y;
    mouse.h += report->h;
    if (IS_LAYER_ON(1)) {
        mouse.v -= report->v;
    } else {
        mouse.v += report->v;
    }
    pointing_device_set_report(mouse);
}ジェスチャー実装(2021-07-31 追記)
当初はスクロールの向きかえたり、ボタンに機能割り当てたり、ってのを想定してたんですが、折角なのでジェスチャーも実装してみました。
実装した機能としては、こんな感じ。
- 戻るボタンを押しながら、カーソルを左右に一定以上動かすと、作業スペース切り替え
 - 戻るボタンを押しながら、カーソルを上に一定以上動かすと、Launchpad 起動して、アプリへアクセス
 - 戻るボタンを押しながら、カーソルを下に一定以上動かすと、動作してるアプリ一覧表示
 - 戻るボタンを押して、カーソルを動かさずにボタンを話すと、戻るボタンとして動作
 
具体的にはこのレポジトリを見てもらえばいいんですが、簡単に説明すると、まず、戻るボタンが押されたタイミングでフラグを立てる。
static void gesture_start(void) {
    dprint("Gesture start\n");
    gesture_wait   = true;
    gesture_move_x = 0;
    gesture_move_y = 0;
}
bool process_record_user(uint16_t keycode, keyrecord_t* record) {
    switch (keycode) {
	    // 中略
	    case GEST:
            if (record -> event.pressed) {
                gesture_start();
            } else if (gesture_wait) {
                tap_code16(LGUI(KC_LBRC));
                gesture_wait = false;
	        }
            break;
        // 中略
}次に、マウスが動くたびに、移動距離を測定し、一定以上動いたら、各機能を発動。非常に簡単。
void process_gesture(void) {
    recognize_gesture(gesture_move_x, gesture_move_y);
    switch (gesture_id) {
        case GESTURE_UP:
	    tap_code16(LCTL(KC_UP));
	    gesture_wait = false;
	    break;
	case GESTURE_DOWN:
	    tap_code16(LCTL(KC_L));
	    gesture_wait = false;
	    break;
	case GESTURE_LEFT:
	    tap_code16(LCTL(KC_LEFT));
	    gesture_wait = false;
	    break;
	case GESTURE_RIGHT:
	    tap_code16(LCTL(KC_RGHT));
	    gesture_wait = false;
	    break;
	case GESTURE_NONE:
	    break;
	default:
	    break;
    }
}
void mouse_report_hook(mouse_parse_result_t const* report) {
    // 中略
    // Save movement to recognize gesture
    //
    if (gesture_wait) {
        gesture_move_x += report->x;
        gesture_move_y += report->y;
	    process_gesture();
    }
}実際につかってみて
実装したとおりに動いていて、なかなかにナイスです。ちょっと高度なことも簡単に実装できますし。エレコムのあれなドライバーとはおさらばです。
ただ、Quantizer 経由だと、マウスのカーソルがちょっとカクカクになってしまいます。がくっと解像度が落ちた感じ。ファームウェアいじって改善できるんでしょうかね。 どうやら、マウス/トラックボールとの相性があるみたいです。手持ちのマウスをささっと調べてみたかぎり、こんな感じ。もし、M-DT2DR を試した人がほかにいれば、ぜひ結果教えてください!
| メーカー | 製品 | 結果 | 
|---|---|---|
| ELECOM | M-DT1DR | 正常 | 
| ELECOM | M-DT2DR | カーソルがカクカク | 
| Logicool | M350 | 正常 | 
てな感じで、今日はここまで。
comments powered by Disqus