
Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: September 28, 2024
Although a computer mouse usually has two to three buttons, on occasion, one might come with extra buttons. So, a situation could arise when we plug the mouse in, and the system doesn’t recognize them. Fortunately, we can often manually configure those buttons.
In this tutorial, we’ll show how to set and register mouse buttons with xremap.
Let’s summarize the approach we take:
The program that listens to events needs to be running continuously. So, ideally, we should run it as a service or daemon at system startup.
In addition, Linux systems use a windowing system to handle device input. In fact, many use X11, so a broad toolset is written for X11. However, newer systems, like Ubuntu 22 and later, switched to Wayland.
Therefore, it’s important to know which system we have when dealing with key events. For that, we check the XDG_SESSION_TYPE environment variable:
$ echo $XDG_SESSION_TYPE
x11
Nonetheless, we work with a tool that supports both windowing systems.
Let’s dive into the implementation, namely xremap, a Rust program.
First, we install Rust and restart the shell.
Next, we can install xremap using Rust’s package manager, cargo:
$ cargo install xremap --features x11
As usual, there are installation options for other systems as well.
Let’s assume we have a trackball mouse with no scroll wheel. So, we might want to configure the extra buttons as a substitute for scrolling.
We start by creating an empty config file:
$ mkdir ~/.config/xremap/
$ touch ~/.config/xremap/config.yml
Next, we run xremap to get the list of available devices:
$ sudo xremap ~/.config/xremap/config.yml
Selecting devices from the following list:
------------------------------------------------------------------------------
/dev/input/event0 : Power Button
/dev/input/event1 : Sleep Button
/dev/input/event2 : AT Keyboard
/dev/input/event3 : Logitech Mouse
...
/dev/input/event7 : HDA Intel Speaker
------------------------------------------------------------------------------
Selected keyboards automatically since --device options weren't specified:
------------------------------------------------------------------------------
/dev/input/event2 : AT Keyboard
------------------------------------------------------------------------------
Logitech Mouse is the device we’re looking for. We can use either the name or the address of the mouse with the –device option. If we skip specifying the device, xremap picks a keyboard.
sudo is necessary because xremap needs device access. In case we get a command not found error, we should make sure the xremap installation path is whitelisted.
Now, let’s find the button names. By running xremap with RUST_LOG=debug and –device options, we see names in the logs when clicking the buttons:
$ sudo RUST_LOG=debug xremap ~/.config/xremap/config.yml --device /dev/input/event3
...
Selected devices matching ["/dev/input/event3"]:
------------------------------------------------------------------------------
/dev/input/event3 : Logitech Mouse
------------------------------------------------------------------------------
[2024-09-26T12:22:02Z DEBUG xremap::event_handler] => 1: BTN_SIDE
[2024-09-26T12:22:02Z DEBUG xremap::action_dispatcher] 1: BTN_SIDE
[2024-09-26T12:22:02Z DEBUG xremap::event_handler] => 0: BTN_SIDE
[2024-09-26T12:22:02Z DEBUG xremap::action_dispatcher] 0: BTN_SIDE
[2024-09-26T12:22:04Z DEBUG xremap::event_handler] => 1: BTN_EXTRA
[2024-09-26T12:22:04Z DEBUG xremap::action_dispatcher] 1: BTN_EXTRA
[2024-09-26T12:22:04Z DEBUG xremap::event_handler] => 0: BTN_EXTRA
[2024-09-26T12:22:04Z DEBUG xremap::action_dispatcher] 0: BTN_EXTRA
So, the buttons are named BTN_SIDE and BTN_EXTRA.
Finally, let’s edit the config file to map the buttons.
With a fairly simple configuration, we map BTN_SIDE and BTN_EXTRA to PAGEUP and PAGEDOWN, respectively:
modmap:
- name: main remaps
remap:
BTN_SIDE: PAGEUP
BTN_EXTRA: PAGEDOWN
We save the changes, then run xremap again:
$ sudo xremap ~/.config/xremap/config.yml --device /dev/input/event3
At this point, clicking the extra mouse buttons should trigger page up and page down events.
To go further, let’s install xdotool, a widely supported input event automation tool:
$ sudo apt install xdotool
An alternative for it on Wayland is ydotool, but it requires manual installation.
We change the configuration to launch xdotool and trigger a more controlled scroll event:
modmap:
- name: main remaps
remap:
BTN_SIDE:
skip_key_event: true
press: { launch: ["xdotool", "click", "4"] }
release: { launch: ["sleep", "0.05"] }
BTN_EXTRA:
skip_key_event: true
press: { launch: ["xdotool", "click", "5"] }
release: { launch: ["sleep", "0.05"] }
Since both press and release are required, we use sleep as a placeholder. Of course, this solution can be developed with a more complex configuration.
In this article, we’ve looked into a basic algorithm for mapping mouse keys. We’ve also showcased a real-world example of configuring mouse buttons using xremap. Although we looked into a simple single key mapping, xremap offers a lot more.