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!

Evoluent VerticalMouse 4; photo by manufacturer

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:

ButtonInput 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 press9
Thumb button (low)10

Notes:

  1. 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.

  2. 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 IDAction
1Left click
2Middle click
3Right click
4Scroll up
5Scroll down
6?
7?
8Back
9Forward
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:

ButtonInput IDOutput IDAction
Index finger11Left click
Middle finger22Middle click
Ring finger33Right click
Wheel scroll up44Scroll up
Wheel scroll down55Scroll down
?66?
?77?
Thumb button (high)89Forward
Wheel press92Middle click
Thumb button (low)108Back

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!