For reasons that I won’t go into here, I switched my desktop computer from an X.Org session to Wayland. One thing that didn’t work was my customised trackball button mapping. That was never particularly user-friendly under X.org, but under Wayland it’s not supported at all. Or rather, it’s delegated to the desktop environment, and as I’m using Gnome, there’s scant customisation available.

But that doesn’t mean we’re out of luck.

I pieced together the solution from a Reddit discussion, and here is a distillation:

First, find the device ID and work out which keyboard IDs (even though it’s not a keyboard) are sent by the device buttons. I had to install the evtest package on Ubuntu to get the evtest command. Select the appropriate device, click the buttons and note what you see. Press control C to finish.

$ sudo evtest
No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0:      Power Button
/dev/input/event1:      Power Button
/dev/input/event2:      Kensington      Kensington Expert Mouse
...
Select the device event number [0-15]: 2
Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0x47d product 0x1020 version 0x110
Input device name: "Kensington      Kensington Expert Mouse"
...
Testing ... (interrupt to exit)
Event: time 1699532550.530269, -------------- SYN_REPORT ------------
Event: time 1699532552.346545, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90003
Event: time 1699532552.346545, type 1 (EV_KEY), code 274 (BTN_MIDDLE), value 1
Event: time 1699532552.346545, -------------- SYN_REPORT ------------
BTN_MIDDLEEvent: time 1699532552.490393, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90003
Event: time 1699532552.490393, type 1 (EV_KEY), code 274 (BTN_MIDDLE), value 0
Event: time 1699532552.490393, -------------- SYN_REPORT ------------
Event: time 1699532554.658501, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90004
Event: time 1699532554.658501, type 1 (EV_KEY), code 275 (BTN_SIDE), value 1
Event: time 1699532554.658501, -------------- SYN_REPORT ------------
Event: time 1699532554.762491, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90004
Event: time 1699532554.762491, type 1 (EV_KEY), code 275 (BTN_SIDE), value 0
Event: time 1699532554.762491, -------------- SYN_REPORT ------------
Event: time 1699532554.778489, type 2 (EV_REL), code 1 (REL_Y), value 1
Event: time 1699532554.778489, -------------- SYN_REPORT ------------
^C

I can see that the device is identified by bus 0x3, vendor 0x47d, and product 0x1020. The last two correspond to the USB device ID. The first one is always 3, for reasons I can’t find explained anywhere.

Below that, I can also see that 90003 is currently sending the middle button code, while 90004 is sending the side button code. I want to swap these.

Although neither Wayland nor Gnome will help me remap the buttons, I can do so at the input device level by writing a custom evdev rule.

In /etc/udev/hwdb.d/90-kensington-expert-mouse.hwdb (call it what you like, only the number is significant), I remap the buttons:

evdev:input:b0003v047Dp1020*
 KEYBOARD_KEY_90004=btn_middle
 KEYBOARD_KEY_90003=btn_side

The first line matches the device by the ID we found earlier, except that:

  1. the 0x is dropped;
  2. leading 0s are added to make each number four digits long;
  3. letters are put into upper case; and
  4. b, v, and p are inserted at the start of each number to identify bus, vendor, and product respectively.

Don’t forget the final *.

All that remains is to reload the rules.

$ sudo systemd-hwdb update

Wait a few seconds, unplug and replug the device, and the buttons should be remapped according to your wishes.