Update (Feb 2021): I ended up switching from X11 to Wayland, so I no longer needed the config or the script described in this post, as they are X11-specific, and my mouse worked exactly as I wanted out-of-the-box with Wayland!
So, you got yourself a new ergonomic mouse, plugged it in, and … well, it works, mostly as you’d expect, but something’s off: some buttons behave funny, while some don’t do anything at all. What’s wrong? Most likely, the button mapping configuration is not what you’d like it to be — so let’s customize the button configuration of our new ergonomic mouse!
What are we doing and why?
Evoluent VerticalMouse is an ergonomic alternative to the standard horizontal mouse or a trackpad. It’s not for everyone, but I found it works quite well for me, which is why I’m using it.
However, simply plugging in the mouse into a USB port may not provide the desired button functionality automatically, and since there is no Linux-specific button customization software available directly from the manufacturer, we need to do it manually ourselves.
This post is an exploration of how to examine and remap the many buttons on this mouse to your liking. Note that the default behavior may differ based on your mouse model as well as your operating system, distribution, and possibly even version, so be sure to customize the config for yourself, rather than copy-pasting the resulting configuration!
Acknowledgements
In the course of research and writing of this post, I learned a lot from this site which covers Evoluent VerticalMouse 3 as well as another post which covers Evoluent VerticalMouse C (which registers itself as version 5).
Thanks to the folks who wrote these posts to help me get started!
I ended up writing this post in the process of figuring out how to configure Evoluent VerticalMouse 4, for which I could not find a guide at the time, but a while after publishing this post, I found this post by the same author as the VerticalMouse C post above, which was exactly what I was looking for! Luckily, we came to the same conclusions.
Overview
At a high-level, the mapping of physical clicks of mouse buttons to actions is as follows:
mouse button → input code → output code → action
Let’s go over each of the translation (arrow) steps in detail.
Mouse button → Input ID
I originally learned about the mapping of the Evoluent mouse to input IDs from this post; however, that post covered VerticalMouse 3 (an older model), while this post will focus on VerticalMouse 4.
As the post suggests, first we need to find out the device id of our mouse, so run the following command:
$ xinput list
and you’ll see an output similar to the following:
⎡ Virtual core pointer [...]
⎜ ↳ Kingsis Peripherals Evoluent VerticalMouse 4 id=12 [...]
⎣ Virtual core keyboard [...]
↳ [...]
The most important thing in this output is that our mouse is device id 12
(this will likely differ for you). Let’s use that device id to see what code is
produced by each of the mouse buttons via:
#!/bin/bash
while true; do
clear
# Be sure to use the device id produced by the output of `xinput list`!
xinput query-state 12
# Alternatively, you can use the full device name:
# xinput query-state "Kingsis Peripherals Evoluent VerticalMouse 4"
# will work as well.
sleep 1
done
Using this script and clicking (and holding) each of the buttons on the mouse, I found the mapping from mouse events to codes to be as follows:
Button | Input ID |
---|---|
Index finger aka Top button | 1 |
Middle finger aka Middle button | 2 |
Ring finger aka Bottom button | 3 |
? | 4 |
? | 5 |
? | 6 |
? | 7 |
Thumb button (high) | 8 |
Wheel press | 9 |
Thumb button (low) | 10 |
Notes:
Although it doesn’t seem to be possible to trigger button input IDs 4 and 5, I believe they are the result of “Scroll up” and “Scroll down”, respectively, so I keep that mapping as-is below.
IDs 6 and 7 appear to be unused, or at least I’m unsure as to how to trigger them. If you know what they are and how to trigger them, please let me know!
Input ID → Output ID
I found a mapping of output IDs to actions on these two blog posts and added what I could figure out, though it’s still slightly incomplete. It’s possible that some codes are not used or not triggerable through this device. If you know what they map to or what they’re used for, let me know!
Output ID | Action |
---|---|
1 | Left click |
2 | Middle click |
3 | Right click |
4 | Scroll up |
5 | Scroll down |
6 | ? |
7 | ? |
8 | Back |
9 | Forward |
10 | ? |
Find out the USB ID for your mouse
To do this, run the command lsusb
and look for the Evoluent VerticalMouse
device. You should see output similar to the following:
$ lsusb
...
Bus 001 Device 004: ID abcd:0123 Evoluent VerticalMouse 4
...
Save the hex identifier abcd:0123
from the output above; you’ll need it later
for configuration.
Putting it all together
Let’s choose the mapping from input IDs (user actions) to the output IDs (computer actions) that we want to take.
I’d like the buttons to map as follows:
- index finger button → left click
- middle finger button → middle click
- ring finger button → right click
Luckily for me, in this case, the mapping is correct as it stands, so there’s nothing to change here. In other cases, for the same mouse, I had to remap these buttons, so double-check our configuration.
Then, I want the top thumb button to be “Forward” and the bottom button be “Back”, so we need to map the buttons as follows:
Button | Input ID | Output ID | Action |
---|---|---|---|
Index finger | 1 | 1 | Left click |
Middle finger | 2 | 2 | Middle click |
Ring finger | 3 | 3 | Right click |
Wheel scroll up | 4 | 4 | Scroll up |
Wheel scroll down | 5 | 5 | Scroll down |
? | 6 | 6 | ? |
? | 7 | 7 | ? |
Thumb button (high) | 8 | 9 | Forward |
Wheel press | 9 | 2 | Middle click |
Thumb button (low) | 10 | 8 | Back |
Thus, keeping in mind the USB ID found in the previous section, our configuration is simply the two middle columns of the table above. Note that the “Input IDs” column must be sorted as it’s not actually part of the input — the output IDs are assumed to be in-order, so we just use it as a guide in the comments to help us keep the mapping correct:
Section "InputClass"
Identifier "Evoluent VerticalMouse 4"
MatchUSBID "abcd:0123"
# input id: 1 2 3 4 5 6 7 8 9 10
Option "ButtonMapping" "1 2 3 4 5 6 7 9 2 8"
EndSection
Note: this config works as-is on Cinnamon; however, my experience with using GNOME 3 has shown that the mouse button mappings will be reset after suspend/resume (and sometimes, but not always, after screen lock/unlock).
My first attempt at a solution was to disable the “active” setting for the mouse plugin:
1. Run the command
dconf-editor
.2. Navigate to the “org / gnome / settings-daemon / plugins / mouse” folder and disable the “active” setting of this plugin. See these Super User and Ask Ubuntu answers for more details and background.
However, while that seemed to work for longer periods of time, it was also temporary.
In the end, before switching away from GNOME 3 to Cinnamon or another desktop manager, I switched from X11 to Wayland and … it just worked. Without any configuration. So now I don’t use this config on Wayland at all, since that config is X11-specific.
If you’re interested in customizing your own button layout, simply use the input ID and output ID mappings, construct the table, and write out your config.
To test the configuration, you can use the xinput
command with the mapping we
created above:
$ xinput set-button-map "Kingsis Peripherals Evoluent VerticalMouse 4" 1 2 3 4 5 6 7 9 2 8
Note that we put quotes around the full name of the device, while for the
button mapping we use the numbers in the line Option "ButtonMapping"
but
without any quotes around the numbers. Note that we don’t need to provide the
input mapping since it’s assumed to be consecutive, just like our “input id”
guiding comment.
However, this setting is temporary: it is only valid for your current X Window session and will be reset next time you reboot your computer. To make it permanent, see the next section.
Installing the configuration
Once you have this configuration, save it to a file; I typically use
90-evoluent.conf
and save it to the appropriate config directory:
$ sudo cp 90-evoluent.conf /usr/share/X11/xorg.conf.d/conf
This config file will take effect when you restart your X Window session.
Aside: what’s in a name? In that directory, you’ll find a bunch of other files with the same name pattern:
[number]-[name].conf
.The number is the priority of config loading, and I feel the mouse doesn’t need to be very early on the priority list, hence the relatively large number.
How different are these button mappings in practice?
I’ve found that an Evoluent VerticalMouse 4 may produce different codes for
different buttons, on distributions as similar as Debian and Ubuntu — in
fact, on one particular distribution version of Debian, the middle button
produced code 3
(not 2
), while the right (bottom) button mapped to code 8
(rather than 3
). Surprisingly, the thumb buttons mapped to forward/back as I
prefer, so I had to do a completely different remapping there than here.
For instance, here’s a config for Cinnamon on Debian to get the same results as above on Ubuntu:
Section "InputClass"
Identifier "Evoluent"
MatchUSBID "abcd:1234"
# input id: 1 2 3 4 5 6 7 8 9
Option "ButtonMapping" "1 2 2 4 5 6 7 3 9"
EndSection
and here’s the equivalent single-line command to try it out:
$ xinput set-button-map "Kingsis Peripherals Evoluent VerticalMouse 4" 1 2 2 4 5 6 7 3 9
Thus, be sure not to copy-paste the configs and commands above, but adapt them to your specific situation to get your ideal configuration!
Closing tips
Once you have your config figured out, don’t forget to save it somewhere safe
— since this config isn’t in your $HOME
directory and is not among your
dotfiles, you might not remember to back it up before switching to a new
computer, but this is one of the important configs as it relates to your mouse
input! Be sure to save it, or better yet, version it along with your other
dotfiles.
Enjoy your ergonomic mouse!