Update July 2024: This article applies only to Linux running the X11 window server. When using Wayland instead – the default since KDE Plasma 6 – none of the below will work. Fortunately Plasma 6’s System Settings let me configure everything I need except Drag Lock. I have used evsieve to implement this.
The Kensington Expert Mouse and Slimblade trackballs have four buttons and a scrollwheel, and I have my personal preference for their layout. There is a utility program available for Windows and macOS to customise the button mapping, but no equivalent program exists for Linux. Fortunately it doesn’t need to, because under Linux there are multiple ways to alter the button-click events sent by input devices; I tried the not-so-new-any-more hotness that is udev before settling on a simple X Windows xorg configuration file. Update Jan 2024: I have an additional requirement; since I use a KVM switch to move between multiple systems I need the configuration to be performed on the fly when the device is detected as having been plugged in. The Xorg approach refused to configure scrolling however, so I currently use a hybrid of mostly X11 xorg configuration plus udev and an xinput script to set scrolling, as explained below.
Xorg
X Windows includes the Xorg configuration file system, usually located at /etc/xorg.conf.d. Following the somewhat standard Linux approach, filenames in this directory should be prefixed with a number between 0 and 100, which denotes the order in which they are processed. Cutting to the chase, I created a file named 50-trackball.conf, with the following content:
Section “InputClass”
Identifier “libinput Kensington trackball”
MatchDevicePath “/dev/input/event*”
MatchVendor “047d”
MatchProduct “Kensington Slimblade Trackball”
Driver “libinput”
Option “ButtonMapping” “3 2 1”
Option “DragLockButtons” “2 3”
Options “Natural Scrolling Enabled” “1”
EndSection
It is necessary to restart X Windows to have it re-read the contents of /etc/xorg.conf.d. The simplest way to achieve this is to log out and back in. Here’s what each line does:
- Identifier “libinput Kensington trackball”
This is simply a label for the entry; can be anything. - MatchDevicePath “/dev/input/event*”
Which /dev input event streams to monitor. I’ve configured this to ‘all of them’ to save me the grief of working out which one the trackball appears at. It might even change each time the trackball is reconnected, I don’t know. - MatchVendor “047d”
- MatchProduct “Kensington Slimblade Trackball”
These are used to decide whether the event data should be filtered. The vendor id can be determined using lsusb – it’s the first of the two hex IDs on the row for the Kensington trackball in that command’s output. - Driver “libinput”
Which device driver I would like to have process events for this stream. - Option “ButtonMapping” “3 2 1”
Okay, finally we’re getting to the meat of this. The syntax here is “which physical button should send left button events, which sends middle button events, and which sends right button events”. “3 2 1” flips the front-left (1) and front-right (3) buttons of the trackball to get left-handed behaviour, whilst assigning the back-left button (2) as middle button. - Option “DragLockButtons” “2 3”
When using a trackball it is not comfortable to hold a button down whilst dragging, so this syntax means that a single click of the back-left button starts a drag at the current cursor position. Front-right terminates the drag at the new current cursor position. - Options “Natural Scrolling Enabled” “1”
Being left-handed, for me anti-clockwise turning of the ball to descend feels “correct”; apparently that corresponds with Natural so far as the Slimblade xinput parameter name reporting is concerned.
The above configuration is fully set-and-forget; I use a KVM switch and yet the configuration is applied faithfully whenever the trackball is assigned to the Linux laptop.
Update Jan 2024
The above did not quite work by itself. I found that the Natural Scrolling Enabled parameter was not being applied when the trackball was connected. Following a comment to this post I learnt that positions 4 and 5 in the ButtonMapping string are “scroll down” and “scroll up”, so I used xev to determine that the Slimblade sends button 5 for an anti-clockwise twist of the ball, and 4 for clockwise, but setting ButtonMapping “3 2 1 5 4” did not work either.
I consequently turned to udev to detect the connection of the trackball and set a semaphore (a write to a named pipe), then wrote a login script that read from the named pipe in order to perform the actual trackball scrolling configuration using xinput. Read on..
Udev
Udev sends events when new devices are plugged in, and one can write rules to trigger actions based on those events. I therefore wrote a udev rule that detected the trackball being connected. Here is the rule (written to a file at /etc/udev/rules.d/80-trackball.rules):
ATTRS{idVendor}=="047d", ATTRS{idProduct}=="2041", OWNER="<your username>", ACTION=="bind", RUN+="/bin/sh -c '/bin/echo connected >> /tmp/TrackballPipe'"
idVendor and idProduct were determined using lsusb; owner is the user as which to perform actions. So far so good, but there is a catch. Udev rules run in a very limited environment, and the X11 environment is not set up. For this reason we cannot call our xinput configuration script directly from the rule’s RUN action, since xinput will complain ‘Unable to connect to X server’. Instead, as you can see, the RUN action simply writes the string ‘connected’ to /tmp/TrackballPipe. Separately, I set up this script to be run as a login script in my KDE environment. The script creates the named pipe and reads from it in a loop, waiting until it finds the string ‘connected’. A pipe is used rather than a file since reads from a pipe block until there is something in the pipe to read, so they are computationally cheap. When the semaphore text arrives, it runs the xinput code to configure the scroll direction, and all is finally right with the world.
Inspiration for the solution described was pieced together from these sources :
https://unix.stackexchange.com/questions/65891/how-to-execute-a-shellscript-when-i-plug-in-a-usb-device
https://unix.stackexchange.com/questions/439478/how-to-set-xinput-properties-triggered-by-udev-device-connection
http://www.reactivated.net/writing_udev_rules.html
https://unix.stackexchange.com/questions/58117/determine-xinput-device-manufacturer-and-model#answer-220082
https://wiki.archlinux.org/title/Libinput
https://bbs.archlinux.org/viewtopic.php?id=261138
by Eduard Drenth
21 Jan 2024 at 04:11
Based on your article and others I felt the need to describe how I made my expert mouse work:
# store as /etc/X11/xorg.conf.d/99-kensington.conf
Section “InputClass”
#
# This identifier is an arbitrary name
#
Identifier “Kensington expert mouse”
#
# here we indicate the device files to be monitored
# we use a wildcard because the ending number varies
#
MatchDevicePath “/dev/input/event*”
#
# This must match the output of xinput list, or evemu-describe
#
MatchProduct “ExpertBT5.0 Mouse”
#
# the driver to use
#
Driver “libinput”
#
# here we assign functions to the mouse buttons
#
# overview of fucntions:
# 1 Left, 2 Middle, 3 Right, 4 Scroll up, 5 Scroll down, 6 Scroll left, 7 Scroll right, 8 Back, 9 Forward
#
# first use xev to find which button fires which function
# 1, 2, 8, 3 for this mouse (left, middle, back, right)
#
# now we can assign a function to a button by putting the event number that is fired
# by that button at the position of the function we want
#
# we assign function middle (2) to the below left button by putting 2 at position 1
# we assign function left (1) to the upper left button by putting 1 at position 2
# we assign function right (3) to the upper right button by putting 8 at position 3
# we assign function back (8) to the below right button by putting 3 at position 8
#
Option “ButtonMapping” “2 1 8 4 5 6 7 3”
#
# Here we specify which button starts a lock for the next button clicked
# We use the event number fired by the button for this
#
Option “DragLockButtons” “3”
EndSection
by Tom Bradford
22 Feb 2024 at 22:06
Migrating from Windows and wanting to bring my Kensington Expert Mouse with me this is just what I need. Kensington, of course, don’t bother to provide a Linux driver and while Mint 20.3 does pick up the mouse on the USB port only the lower right and left buttons work and I’d like to use the top two as I did in Windows.
Unfortunately I don’t understand a word of the above,
by admin
22 Feb 2024 at 22:37
Hi Tom,
Go read the articles I list as inspiration, especially the last three. If it’s only button config you need then the only part of my solution you need is the Xorg part. Crucially the ButtonMapping. Read up about that and experiment with the order of the numbers in that line until you get the behaviour you’re after.
HTH,
Ian