Ubuntu 18.04でLogicool MX Master 3をカスタマイズする

まえがき

HHKBに合わせてLogicool MX Master 3をぽちった。
しかしWindows/Mac以外だとデフォルトではジェスチャーボタンやモードシフト、戻る、進むボタンが使えない。
調べたらlogiopsというOSSで色々とカスタマイズが可能っぽかったので設定したときのメモを残しておく。

github.com

インストール

$ apt install cmake 
$ git clone git@github.com:PixlOne/logiops.git
$ cd logiops/
$ mkdir build
$ cd build
$ cmake ..
$ make
$ sudo make install

libconfig.h++が存在しない

$ make
[ 88%] Built target hidpp
[ 89%] Building CXX object src/logid/CMakeFiles/logid.dir/logid.cpp.o
In file included from /home/st1t/github.com/logiops/src/logid/Device.h:6:0,
                 from /home/st1t/github.com/logiops/src/logid/Actions.h:3,
                 from /home/st1t/github.com/logiops/src/logid/util.h:4,
                 from /home/st1t/github.com/logiops/src/logid/logid.cpp:12:
/home/st1t/github.com/logiops/src/logid/Configuration.h:5:10: fatal error: libconfig.h++: そのようなファイルやディレクトリはありません
 #include <libconfig.h++>
          ^~~~~~~~~~~~~~~
compilation terminated.
src/logid/CMakeFiles/logid.dir/build.make:62: recipe for target 'src/logid/CMakeFiles/logid.dir/logid.cpp.o' failed
make[2]: *** [src/logid/CMakeFiles/logid.dir/logid.cpp.o] Error 1
CMakeFiles/Makefile2:87: recipe for target 'src/logid/CMakeFiles/logid.dir/all' failed
make[1]: *** [src/logid/CMakeFiles/logid.dir/all] Error 2
Makefile:129: recipe for target 'all' failed
make: *** [all] Error 2
$ 

$ sudo apt install libconfig++-dev
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
以下の追加パッケージがインストールされます:
  libconfig++9v5
以下のパッケージが新たにインストールされます:
  libconfig++-dev libconfig++9v5
アップグレード: 0 個、新規インストール: 2 個、削除: 0 個、保留: 0 個。
65.7 kB のアーカイブを取得する必要があります。
この操作後に追加で 304 kB のディスク容量が消費されます。
続行しますか? [Y/n] Y
取得:1 http://jp.archive.ubuntu.com/ubuntu bionic/universe amd64 libconfig++9v5 amd64 1.5-0.4 [31.6 kB]
取得:2 http://jp.archive.ubuntu.com/ubuntu bionic/universe amd64 libconfig++-dev amd64 1.5-0.4 [34.1 kB]
65.7 kB を 0秒 で取得しました (844 kB/s)   
以前に未選択のパッケージ libconfig++9v5:amd64 を選択しています。
(データベースを読み込んでいます ... 現在 389870 個のファイルとディレクトリがインストールされています。)
.../libconfig++9v5_1.5-0.4_amd64.deb を展開する準備をしています ...
libconfig++9v5:amd64 (1.5-0.4) を展開しています...
以前に未選択のパッケージ libconfig++-dev:amd64 を選択しています。
.../libconfig++-dev_1.5-0.4_amd64.deb を展開する準備をしています ...
libconfig++-dev:amd64 (1.5-0.4) を展開しています...
libconfig++9v5:amd64 (1.5-0.4) を設定しています ...
libconfig++-dev:amd64 (1.5-0.4) を設定しています ...
libc-bin (2.27-3ubuntu1) のトリガを処理しています ...
$ 
$ make
$ sudo make install
[ 88%] Built target hidpp
[100%] Built target logid
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/bin/logid
-- Set runtime path of "/usr/local/bin/logid" to ""
-- Installing: /lib/systemd/system/logid.service
-- Installing: /usr/local/include/hidpp
-- Installing: /usr/local/include/hidpp/misc
-- Installing: /usr/local/include/hidpp/misc/CRC.h
-- Installing: /usr/local/include/hidpp/misc/Log.h
-- Installing: /usr/local/include/hidpp/misc/Endian.h
-- Installing: /usr/local/include/hidpp/misc/EventQueue.h
-- Installing: /usr/local/include/hidpp/hid
-- Installing: /usr/local/include/hidpp/hid/RawDevice.h
-- Installing: /usr/local/include/hidpp/hid/UsageStrings.h
-- Installing: /usr/local/include/hidpp/hid/DeviceMonitor.h
-- Installing: /usr/local/include/hidpp/hid/windows
-- Installing: /usr/local/include/hidpp/hid/windows/DeviceData.h
-- Installing: /usr/local/include/hidpp/hid/windows/error_category.h
-- Installing: /usr/local/include/hidpp/hidpp
-- Installing: /usr/local/include/hidpp/hidpp/AbstractProfileDirectoryFormat.h
-- Installing: /usr/local/include/hidpp/hidpp/AbstractMacroFormat.h
-- Installing: /usr/local/include/hidpp/hidpp/DeviceInfo.h
-- Installing: /usr/local/include/hidpp/hidpp/ProfileDirectory.h
-- Installing: /usr/local/include/hidpp/hidpp/Report.h
-- Installing: /usr/local/include/hidpp/hidpp/Dispatcher.h
-- Installing: /usr/local/include/hidpp/hidpp/SettingLookup.h
-- Installing: /usr/local/include/hidpp/hidpp/AbstractProfileFormat.h
-- Installing: /usr/local/include/hidpp/hidpp/AbstractMemoryMapping.h
-- Installing: /usr/local/include/hidpp/hidpp/defs.h
-- Installing: /usr/local/include/hidpp/hidpp/Enum.h
-- Installing: /usr/local/include/hidpp/hidpp/Profile.h
-- Installing: /usr/local/include/hidpp/hidpp/SimpleDispatcher.h
-- Installing: /usr/local/include/hidpp/hidpp/Setting.h
-- Installing: /usr/local/include/hidpp/hidpp/Macro.h
-- Installing: /usr/local/include/hidpp/hidpp/Address.h
-- Installing: /usr/local/include/hidpp/hidpp/DispatcherThread.h
-- Installing: /usr/local/include/hidpp/hidpp/Device.h
-- Installing: /usr/local/include/hidpp/hidpp/ids.h
-- Installing: /usr/local/include/hidpp/hidpp/Field.h
-- Installing: /usr/local/include/hidpp/hidpp10
-- Installing: /usr/local/include/hidpp/hidpp10/ProfileFormatG9.h
-- Installing: /usr/local/include/hidpp/hidpp10/ProfileFormatG500.h
-- Installing: /usr/local/include/hidpp/hidpp10/DeviceInfo.h
-- Installing: /usr/local/include/hidpp/hidpp10/ProfileFormatCommon.h
-- Installing: /usr/local/include/hidpp/hidpp10/ProfileFormat.h
-- Installing: /usr/local/include/hidpp/hidpp10/ProfileDirectoryFormat.h
-- Installing: /usr/local/include/hidpp/hidpp10/RAMMapping.h
-- Installing: /usr/local/include/hidpp/hidpp10/IMemory.h
-- Installing: /usr/local/include/hidpp/hidpp10/MacroFormat.h
-- Installing: /usr/local/include/hidpp/hidpp10/IResolution.h
-- Installing: /usr/local/include/hidpp/hidpp10/IProfile.h
-- Installing: /usr/local/include/hidpp/hidpp10/Sensor.h
-- Installing: /usr/local/include/hidpp/hidpp10/defs.h
-- Installing: /usr/local/include/hidpp/hidpp10/IReceiver.h
-- Installing: /usr/local/include/hidpp/hidpp10/MemoryMapping.h
-- Installing: /usr/local/include/hidpp/hidpp10/ProfileFormatG700.h
-- Installing: /usr/local/include/hidpp/hidpp10/IIndividualFeatures.h
-- Installing: /usr/local/include/hidpp/hidpp10/Device.h
-- Installing: /usr/local/include/hidpp/hidpp10/Error.h
-- Installing: /usr/local/include/hidpp/hidpp10/WriteError.h
-- Installing: /usr/local/include/hidpp/hidpp20
-- Installing: /usr/local/include/hidpp/hidpp20/IBatteryLevelStatus.h
-- Installing: /usr/local/include/hidpp/hidpp20/IReset.h
-- Installing: /usr/local/include/hidpp/hidpp20/ProfileFormat.h
-- Installing: /usr/local/include/hidpp/hidpp20/IWirelessDeviceStatus.h
-- Installing: /usr/local/include/hidpp/hidpp20/ProfileDirectoryFormat.h
-- Installing: /usr/local/include/hidpp/hidpp20/MacroFormat.h
-- Installing: /usr/local/include/hidpp/hidpp20/IReprogControls.h
-- Installing: /usr/local/include/hidpp/hidpp20/UnsupportedFeature.h
-- Installing: /usr/local/include/hidpp/hidpp20/defs.h
-- Installing: /usr/local/include/hidpp/hidpp20/MemoryMapping.h
-- Installing: /usr/local/include/hidpp/hidpp20/IRoot.h
-- Installing: /usr/local/include/hidpp/hidpp20/FeatureInterface.h
-- Installing: /usr/local/include/hidpp/hidpp20/IHiresScroll.h
-- Installing: /usr/local/include/hidpp/hidpp20/IFeatureSet.h
-- Installing: /usr/local/include/hidpp/hidpp20/ISmartShift.h
-- Installing: /usr/local/include/hidpp/hidpp20/ITouchpadRawXY.h
-- Installing: /usr/local/include/hidpp/hidpp20/IAdjustableDPI.h
-- Installing: /usr/local/include/hidpp/hidpp20/Device.h
-- Installing: /usr/local/include/hidpp/hidpp20/Error.h
-- Installing: /usr/local/include/hidpp/hidpp20/IOnboardProfiles.h
-- Installing: /usr/local/include/hidpp/hidpp20/IMouseButtonSpy.h
-- Installing: /usr/local/include/hidpp/hidpp20/ILEDControl.h
-- Installing: /usr/local/lib/libhidpp.so
$
$ sudo systemctl enable logid

libhidpp.soがない

$ /usr/local/bin/logid --help
/usr/local/bin/logid: error while loading shared libraries: libhidpp.so: cannot open shared object file: No such file or directory

github.com

try symlinking /usr/lib/libhidpp.so to /usr/local/lib/libhidpp.so

って書いてあるが、

$ ls -la /usr/local/lib/libhidpp.so
-rw-r--r-- 1 root root 2407952  3月  9 20:14 /usr/local/lib/libhidpp.so
$ 

既にある。 実際どこを見に行ってるか確認すると、/usr/lib/libhidpp.soっぽい

$ strace -e trace=openat logid 2>&1 | grep libhidpp.so
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/tls/haswell/x86_64/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/tls/haswell/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/tls/x86_64/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/tls/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/haswell/x86_64/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/haswell/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/x86_64/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/tls/haswell/x86_64/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/tls/haswell/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/tls/x86_64/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/tls/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/haswell/x86_64/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/haswell/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/x86_64/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/tls/haswell/x86_64/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/tls/haswell/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/tls/x86_64/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/tls/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/haswell/x86_64/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/haswell/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/tls/haswell/x86_64/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/tls/haswell/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/tls/x86_64/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/tls/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/haswell/x86_64/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/haswell/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/libhidpp.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
logid: error while loading shared libraries: libhidpp.so: cannot open shared object file: No such file or directory
$ 
$ sudo ln -s /usr/local/lib/libhidpp.so /usr/lib/libhidpp.so
$ logid --help
Usage: logid [options]
Possible options are:
    -v,--verbose [level]       Set log level to debug/info/warn/error (leave blank for debug)
    -c,--config [file path]    Change config file from default at /etc/logid.cfg
    -h,--help                  Print this message.
$ 

設定ファイルを用意する

$ sudo vim /etc/logid.cfg
devices: (
{
    name: "MX Master 3";
    smartshift:
    {
        on: false;
        threshold: 30;
    };
    hiresscroll:
    {
        hires: false;
        invert: false;
        target: false;
    };
    dpi: 1000;

    buttons: (
        {
            # 戻るボタン
            cid: 0x53;
            action =
            {
                type: "Keypress";
                keys: ["KEY_LEFTALT","KEY_LEFT"];
            };
        },
        {
            # 進むボタン
            cid: 0x56;
            action =
            {
                type: "Keypress";
                keys: ["KEY_LEFTALT","KEY_RIGHT"];
            };
        },
        {
            # ジェスチャーボタン
            cid: 0xc3;
            action =
            {
                type: "Gestures";
                gestures: (
                    {
                        direction: "Up";
                        mode: "OnRelease";
                        action =
                        {
                            type: "Keypress";
                            keys: ["KEY_LEFTALT","KEY_LEFTCTRL","KEY_UP"];
                        };
                    },
                    {
                        direction: "Down";
                        mode: "OnRelease";
                        action =
                        {
                            type: "Keypress";
                            keys: ["KEY_LEFTALT","KEY_LEFTCTRL","KEY_DOWN"];
                        };
                    },
                    {
                        direction: "Left";
                        mode: "OnRelease";
                        action =
                        {
                            type: "Keypress";
                            keys: ["KEY_LEFTSHIFT","KEY_LEFTALT","KEY_LEFTCTRL","KEY_DOWN"];
                        };
                    },
                    {
                        direction: "Right";
                        mode: "OnRelease";
                        action =
                        {
                            type: "Keypress";
                            keys: ["KEY_LEFTSHIFT","KEY_LEFTALT","KEY_LEFTCTRL","KEY_UP"];
                        }
                    },
                    {
                        direction: "None";
                        mode: "OnRelease";
                        action =
                        {
                            type: "Keypress";
                            keys: ["KEY_LEFTCTRL","KEY_W"];
                        }
                    }
                );
            };
        },
        {
            # SmartShiftボタン
            cid: 0xc4;
            action =
            {
                type = "ToggleSmartshift";
            };
        }
    );
}
);