メモ:Linuxで Magic Trackpad 2 を設定する

公開日

原文言語: 中国語 。 AI翻訳: 英語 日本語


手首の健康のため


マウスを使い続けると、手首や前腕がどうしてもつらくなる。
液タブに替えてからは問題なくなった。

ところが最近、その液タブの内蔵バッテリーが膨らみ始めている気がする(ちょっと怖い…)。それに以前から Magic Trackpad 2 が気になっていた。
手首の健康のため、大金をはたいて Appleの Magic Trackpad 2 を購入。

開封してみると、思ったより小さくて、なかなか精密な小板。
Bluetoothでつなぐだけで Windows / Linux どちらでも一応使えるが、左クリック/右クリック程度の基本操作だけ。Windowsの3本指タスク切り替えみたいなジェスチャーはデフォルトでは動かない。
というわけで、もう一段設定が必要になった。


Windows 側の設定

Windows は超簡単。既にドライバを作ってくれている人がいるので、インストールするだけ。
プロジェクト:Github - imbushuo/mac-precision-touchpad

手順通りに入れると、Trackpadが多指ジェスチャーに対応し、ノートPC内蔵タッチパッドとほぼ同じ感覚で使える。

Linux 側の設定

Linux は少しだいぶ面倒だった。設定中にいくつか大量にハマったのでメモしておく。

1回目の設定(失敗)

Manjaro の設定画面にもタッチパッド設定はあるが、基本機能だけで多指ジェスチャーは設定できない。
しかもなぜか、スリープ復帰後に設定がデフォルトへ戻ることがある(ポインタ速度、スクロール方向など)。さらに、設定画面で変更し直しても反映されないことがあって謎。

仕方ないのでGUI設定は諦めて、自力で設定する。
まず見つけたのがこのチュートリアル:Configure Apple Magic Trackpad 2 Gestures on Manjaro KDE
ちょうど欲しい内容っぽかったので、ざっと見て手順通り進めた。

  • sudo pacman -S libinput-gestures
    libinput-gestures をインストール。ジェスチャーに好きなアクションを割り当てられる。

  • sudo gpasswd -a $USER input
    自分のユーザーを input グループに追加。

  • 次に libinput-gestures サービスを起動

    • libinput-gestures-setup start 起動
    • libinput-gestures-setup stop 停止
    • よく使うのは restart|autostart|status
  • 起動はできたっぽい。次はジェスチャー設定。
    設定ファイルは2箇所に置ける:
    /etc/libinput-gestures.conf はシステム全体の設定(デフォルトあり)
    ~/.config/libinput-gestures.conf はユーザーごとの設定(自分で書く)
    だいたい ~/.config/libinput-gestures.conf に必要分を書けばOK。

  • 書いたら再起動:libinput-gestures-setup restart

ところが手順通りに設定しても、ジェスチャーが一切反応しない。
libinput-gestures -d でデバッグしても、トラックパッドを触っても何も出ない。イベント自体を受け取れていないように見える。

しばらく粘ったが成果なし。いったん撤退(この板を使いこなせないのではと一瞬思った)。


2回目の挑戦(原因が分かった)

2週間後、たまたま libinput を見返していて、libinput-gestureslibinput からイベントを受け取り、設定ファイルに従ってジェスチャーを発火しているのでは?と思い至った。
つまり libinput-gestures がイベントを受け取れていないなら、そもそも libinput 側はどうなのか?

  • まずは libinput の使い方を確認

    Terminal window
    $ libinput -h
    Usage: libinput [--help|--version] <command> [<args>]
    Global options:
    --help ...... show this help and exit
    --version ... show version information and exit
    Commands:
    list-devices
    List all devices with their default configuration options
    debug-events
    Print events to stdout
    debug-gui
    Display a simple GUI to visualize libinput's events.
    measure <feature>
    Measure various device properties. See the man page for more info
    analyze <feature>
    Analyze device events. See the man page for more info
    record
    Record event stream from a device node. See the man page for more info
    replay
    Replay a previously recorded event stream. See the man page for more info
  • まず libinput が Trackpad を認識できているか確認する
    libinput list-devices
    いろいろ出てくるので、その中からTrackpadを探すと、だいたいこんな感じ:

    Terminal window
    Device: Apple Inc. Magic Trackpad 2
    Kernel: /dev/input/event11
    Group: 4
    Seat: seat0, default
    Size: 162x115mm
    Capabilities: pointer gesture
    Tap-to-click: disabled
    Tap-and-drag: enabled
    Tap drag lock: disabled
    Left-handed: disabled
    Nat.scrolling: disabled
    Middle emulation: disabled
    Calibration: n/a
    Scroll methods: *two-finger edge
    Click methods: button-areas *clickfinger
    Disable-w-typing: n/a
    Disable-w-trackpointing: n/a
    Accel profiles: flat *adaptive custom
    Rotation: n/a
    Device: Apple Inc. Magic Trackpad 2
    Kernel: /dev/input/event13
    Group: 4
    Seat: seat0, default
    Size: 162x115mm
    Capabilities: pointer gesture
    Tap-to-click: disabled
    Tap-and-drag: enabled
    Tap drag lock: disabled
    Left-handed: disabled
    Nat.scrolling: disabled
    Middle emulation: disabled
    Calibration: n/a
    Scroll methods: *two-finger edge
    Click methods: button-areas *clickfinger
    Disable-w-typing: n/a
    Disable-w-trackpointing: n/a
    Accel profiles: flat *adaptive custom
    Rotation: n/a

    しかしおかしいことに、Trackpad が 2つ 見つかった。接続しているのは1台のはずなのに。

    後から振り返ると、これが犯人だった。

  • 次に libinput がイベントを受け取れているか確認
    libinput debug-events /dev/input/event11 を実行して、適当にトラックパッドを触ってみる

    Terminal window
    event11 DEVICE_ADDED Apple Inc. Magic Trackpad 2 seat0 default group1 cap:pg size 162x115mm tap(dl off)
    event11 POINTER_MOTION +0.012s 0.00/ 1.04 ( +0.00/ +5.34)
    event11 POINTER_MOTION +0.022s 0.00/ 0.72 ( +0.00/ +3.20)
    event11 POINTER_MOTION +0.034s 0.00/ 1.20 ( +0.00/ +5.34)
    event11 GESTURE_HOLD_BEGIN +0.040s 1
    event11 POINTER_MOTION +0.045s -0.22/ 1.44 ( -1.00/ +6.41)
    event11 POINTER_MOTION +0.056s -0.90/ 1.67 ( -4.00/ +7.48)
    event11 GESTURE_HOLD_END +0.056s 1 cancelled
    event11 POINTER_MOTION +0.067s -1.79/ 2.39 ( -8.00/+10.68)
    event11 POINTER_MOTION +0.079s -2.69/ 2.39 (-12.00/+10.68)
    event11 POINTER_MOTION +0.090s -3.36/ 2.87 (-15.00/+12.82)
    event11 POINTER_MOTION +0.101s -6.49/ 5.74 (-29.00/+25.64)
    event11 POINTER_MOTION +0.112s -7.16/ 4.78 (-32.00/+21.36)
    event11 POINTER_MOTION +0.124s -8.51/ 5.26 (-38.00/+23.50)
    event11 POINTER_MOTION +0.135s -9.18/ 5.02 (-41.00/+22.43)
    event11 POINTER_MOTION +0.146s -6.72/ 2.87 (-30.00/+12.82)
    event11 POINTER_MOTION +0.157s -9.63/ 4.31 (-43.00/+19.23)
    event11 POINTER_MOTION +0.169s -9.40/ 3.35 (-42.00/+14.95)
    event11 POINTER_MOTION +0.180s -8.51/ 2.87 (-38.00/+12.82)
    event11 POINTER_MOTION +0.191s -4.70/ 0.72 (-21.00/ +3.20)
    ...

    OK。libinput はイベントをたくさん出力した。

  • つまり問題は libinput は読めるのに libinput-gestures は読めない、ということ。
    次に libinput-gestures --help を見て、使い方を確認する。

    Terminal window
    $ libinput-gestures --help
    usage: libinput-gestures [-h] [-c CONFFILE] [-v] [-d] [-r] [-l] [--device DEVICE]
    Read gestures from libinput touchpad and action shell commands.
    options:
    -h, --help show this help message and exit
    -c CONFFILE, --conffile CONFFILE
    alternative configuration file
    -v, --verbose output diagnostic messages
    -d, --debug output diagnostic messages only, do not action gestures
    -r, --raw output raw libinput debug-event messages only, do not action gestures
    -l, --list just list out environment and configuration
    --device DEVICE explicit device name to use (or path if starts with /)

    雰囲気としては:
    -d は設定したジェスチャーが発火しているかを見る
    -rlibinput から受け取った生イベントを出す
    「そもそもイベントを受け取れているか」を見たいなら -r が良い
    (このへんは全部終わった後に分かった。当時は手当たり次第に試していた)

    libinput-gestures-setup stoplibinput-gestures サービスを停止
    libinput-gestures -r --device /dev/input/event11event11 のイベントが読めるか確認

    Terminal window
    $ libinput-gestures -r --device /dev/input/event11
    libinput-gestures: session KDE+x11 on Linux-6.1.**
    Hash: **
    device /dev/input/event11
    libinput-gestures: device /dev/input/event11: Apple Inc. Magic Trackpad 2
    -event11 DEVICE_ADDED Apple Inc. Magic Trackpad 2 seat0 default group1 cap:pg size 162x115mm tap(dl off)
    event11 POINTER_MOTION +0.867s 2.59/ 0.00 (+13.00/ +0.00)
    event11 POINTER_MOTION +0.878s 3.58/ 0.24 (+16.00/ +1.07)
    event11 POINTER_MOTION +0.889s 3.81/ 0.24 (+17.00/ +1.07)
    event11 POINTER_MOTION +0.900s 3.81/ 0.72 (+17.00/ +3.20)
    event11 POINTER_MOTION +0.912s 3.58/ 0.48 (+16.00/ +2.14)
    event11 POINTER_MOTION +0.923s 3.13/ 0.48 (+14.00/ +2.14)
    event11 POINTER_MOTION +0.934s 2.69/ 0.00 (+12.00/ +0.00)
    event11 POINTER_MOTION +0.945s 2.24/ 0.24 (+10.00/ +1.07)
    event11 POINTER_MOTION +0.957s 1.79/ 0.00 ( +8.00/ +0.00)
    event11 POINTER_MOTION +0.968s 2.46/ 0.24 (+11.00/ +1.07)

    libinput と同じように libinput-gestures もイベントをたくさん出力した。つまり event11 側は問題なし。

    次に libinput-gestures -r --device /dev/input/event13 を試して、もう一方の“Trackpad”デバイスが何者か確認する。

    Terminal window
    $ libinput-gestures -r --device /dev/input/event13
    libinput-gestures: session KDE+x11 on Linux-6.1.**
    Hash: **
    device /dev/input/event13
    libinput-gestures: device /dev/input/event13: Apple Inc. Magic Trackpad 2
    -event13 DEVICE_ADDED Apple Inc. Magic Trackpad 2 seat0 default group1 cap:pg size 162x115mm tap(dl off)

    どれだけトラックパッドを操作しても、このデバイスはイベントを一切出さない。

  • 現状:なぜかPC上にトラックパッドデバイスが2つある。/dev/input/event11/dev/input/event13
    前者は動くが、後者は無反応。

    libinput-gestures -d も見てみる。

    Terminal window
    $ libinput-gestures -d
    libinput-gestures: session KDE+x11 on Linux-6.1.**
    Hash: **
    Gestures configured in ~/.config/libinput-gestures.conf:
    swipe up 4 xdotool key ctrl+super+Down
    swipe down 4 xdotool key ctrl+super+Up
    swipe left 4 xdotool key ctrl+super+Right
    swipe right 4 xdotool key ctrl+super+Left
    libinput-gestures: device /dev/input/event13: Apple Inc. Magic Trackpad 2

原因判明:libinput-gestures がデフォルトで /dev/input/event13(イベントが来ない方)を使っていた。

なぜ2台認識され、しかも片方が無反応なのか:
推測だけど、最初にLightningケーブルで有線接続を試して、その後Bluetooth接続も試した。
ところが何らかの理由で、以前の有線接続のデバイスが消えずに残った。
そして libinput-gestures がたまたまその“死んでる方”を掴んだ…悲しい。


libinput-gestures に正しいデバイスを使わせる

対策は簡単で、イベントが来る /dev/input/event11libinput-gestures に指定して使わせればいい。

設定方法は /etc/libinput-gestures.conf(システム設定)に書いてあった気がしたので、開いて読んでみた。

###############################################################################
This application normally determines your touchpad device
automatically. Some users may have multiple touchpads but by default
we use only the first one found. However, you can choose to specify
the explicit device name to use. Run "libinput list-devices" to work
out the name of your device (from the "Device:" field). Then add a
device line specifying that name, e.g:
#
device DLL0665:01 06CB:76AD Touchpad
#
If the device name starts with a '/' then it is instead considered as
the explicit device path although since device paths can change
through reboots this is best to be a symlink. E.g. instead of specifying
/dev/input/event12, you should use the corresponding full path link
under /dev/input/by-path/ or /dev/input/by-id/.
#
You can choose to use ALL touchpad devices by setting the device name
to "all". E.g. Do this if you have multiple touchpads which you want
to use in parallel. This reduces performance slightly so only set this
if you have to.
#
device all

開発者が設定ファイル内で丁寧に書いていた:libinput-gestures はデフォルトで「見つかった最初のデバイス」を使う。
複数デバイスがある場合は、明示的に指定できる。

Terminal window
device /dev/input/event11
device /dev/input/by-path/pci-0000:00:****-event-mouse
device /dev/input/by-id/usb-Apple_Inc._Magic_Trackpad_2_****-event-mouse

試してみたら、上の3つの書き方はいずれも特定デバイスを指定できた。
ただし開発者の説明通り、event11 の番号は固定ではなく、再起動ごとに変わる可能性がある。
なので、できれば by-path または by-id の安定したパスで指定するのが良い。

ただ、もっと雑で強い方法もある:

Terminal window
device all

すべてのタッチパッドデバイスを同時に使う(代わりに少し性能が落ちる)。

少し考えて、私は device all にした。
トラックパッドは充電のために有線でつなぐこともあるし、Bluetoothが不安定なら有線に切り替えることもある。
PCは有線とBluetoothを別デバイスとして扱うので、Bluetooth側を by-path/by-id で固定してしまうと、有線に切り替えた瞬間に設定が効かなくなる。
だから割り切って device all


xinput でトラックパッド設定をCLIから変える

libinput-gestures の問題は解決して、多指ジェスチャーも認識できるようになった。
次はポインタ速度やスクロール方向など、トラックパッドの設定を調整したい。

本来ならGUIの設定画面で変えられる。
でも冒頭に書いた通り、スリープ復帰後に設定が飛んでデフォルトに戻ることがあり、しかもGUIから再設定できないことがある。

そこでコマンドラインで設定する方法を探した。
いろいろ見た結果、xinput が一番手軽そうだった。
使い方は ArchWiki - xinput を参照。要点は:

  • xinput list でデバイスを探す
  • xinput list-props device で変更できるプロパティを確認
  • xinput set-prop device property values で値を設定

ここでも同じ問題に遭遇した。xinput もトラックパッドを2つ認識していた。

Terminal window
$ xinput list
Virtual core pointer id=2 [master pointer (3)]
Virtual core XTEST pointer id=4 [slave pointer (2)]
Logi K855 Keyboard id=11 [slave pointer (2)]
Apple Inc. Magic Trackpad 2 id=9 [slave pointer (2)]
Apple Inc. Magic Trackpad 2 id=13 [slave pointer (2)]
Virtual core keyboard id=3 [master keyboard (2)]
Virtual core XTEST keyboard id=5 [slave keyboard (3)]
Power Button id=6 [slave keyboard (3)]
Power Button id=7 [slave keyboard (3)]
Sleep Button id=8 [slave keyboard (3)]
CSCTEK USB Audio and HID id=10 [slave keyboard (3)]
Logi K855 Keyboard id=12 [slave keyboard (3)]

考えた末、libinput-gestures と同じ方針にした。どっちが本物か分からないなら、両方設定してしまえばいい。

設定方法はこのあたりを参考にした:
Stack Overflow - ‘xinput list’ shows same device twice & device IDs change: how to use ‘set-prop’ in a script?
Stack Overflow - How to make a program that finds id’s of xinput devices and sets xinput some settings

そして動くスクリプトを雑に継ぎ接ぎして完成:

Terminal window
# Setup Apple Magic Trackpad 2
# Get all trackpad device ids
ids=$(xinput --list | grep "Trackpad" | cut -d '=' -f 2 | cut -f 1)
for id in $ids
do
xinput set-prop $id "libinput Accel Speed" 0.5
xinput set-prop $id "libinput Natural Scrolling Enabled" 1
done
libinput-gestures-setup restart
systemctl --user restart libinput-gestures.service

これを .bashrc に入れておけば、トラックパッドが怪しくなったときに Ctrl+Alt+T でターミナルを開いて再実行するだけで、またスムーズに戻る。

スクリプト末尾の2行は、libinput-gestures がたまに死ぬので再起動が必要になるため。
libinput-gestures-setup restart で再起動できる。
あるいは libinput-gesturessystemd のユーザーサービスに登録して、スクリプトの systemctl で再起動してもよい。
systemd の設定は公式ドキュメント参照: Github - bulletmark/libinput-gestures - SYSTEMD USER SERVICE

まとめ

今回の問題は、libinput がトラックパッドを2つ認識し、libinput-gestures がデフォルトで“死んでる方”を掴んでいたせいで、設定が全部効かなかったという話。
いろいろ探して、結局「解決策はドキュメントに明確に書いてある」ことが分かった。ただ最初にちゃんと読んでいなかった…悲。無駄に時間を溶かした。
教訓:ちゃんとドキュメントを読む。

Trackpad 2 使用感

全体的には満足。Bluetooth接続で1週間使って電池がだいたい20%減るくらい(厳密には測ってないけどその程度)で、バッテリーはそこそこ持つ。
Bluetoothは遅延が少し大きい気がするし、有線ほど安定しない。たまに無反応になって、数秒待つと復帰することがある。
それ以外は満足。お金は無駄じゃなかった

トレイアイコンが消える

しばらく使っていると、なぜかトレイアイコンがいくつか消えたり、キーボードレイアウトがUSに戻って変更できなくなったりすることがあった。トラックパッドの切断/再接続と関係があるかは不明。
トレイを再起動するコマンドを探して、.bashrc にエイリアスを追加:

Terminal window
alias tray_restart='kded5 --replace > /dev/null 2>&1 &'

トレイアイコンが消えたときは tray_restart で復活する。