Use more mouse buttons!

The multi-button mouse is a  really common thing today, however we are still not taking the advantage they can provide us.

Until now I was using my extra buttons only for gaming. Maybe because they not make it easy to use them.  Even under Windwos only the Logitech Gaming Software offers a comfortable solution to map custom actions or key combinations to a mouse button.

Of course the option is given under Linux as well, however you have to create you own CLI magic to make it work, because there is no easy to use universal solution with GUI for such task.

I was planning to map those operations to a mouse button for a long time, because I need to use special key combinations for inter-VM copy paste under Qubes OS

To make that possible we need to know how is a mouse button pressing event looks like under the hood. For the first step we have to identify the correct input device:

[user@dom0 ~]$ xinput --list
 ⎡ Virtual core pointer           id=2 [master pointer  (3)]
 ⎜  ↳ Virtual core XTEST pointer  id=4 [slave pointer   (2)]
 ⎜  ↳ SynPS/2 Synaptics TouchPad  id=10 [slave pointer  (2)]
 ⎜  ↳ TPPS/2 IBM TrackPoint       id=11 [slave pointer  (2)]
 ⎜  ↳ sys-usb: Logitech M705      id=14 [slave pointer  (2)]
 ⎣ Virtual core keyboard          id=3 [master keyboard (2)]
   ↳ Virtual core XTEST keyboard  id=5 [slave keyboard  (3)]
   ↳ Power Button                 id=6 [slave keyboard  (3)]
   ↳ Video Bus                    id=7 [slave keyboard  (3)]
   ↳ Sleep Button                 id=8 [slave keyboard  (3)]
   ↳ AT Translated Set 2 keyboard id=9 [slave keyboard  (3)]
   ↳ ThinkPad Extra Buttons       id=12 [slave keyboard (3)]

You may get different results, but the essence is to find your input device id. For me it was the Logitech M705 wit the id 14. The only Qubes OS specific thing that my mouse has been attached to a special VM called sys-usb. Thanks to the qubes input proxy service only controlled and valid mouse events are getting to dom0. This solution make us immune to MouseJack, and any similar attack as well!

Beside that, the mouse button mapping solution should work the same way in any Linux distribution, as it was described in this blog post long time ago.

As we have the correct ID we are ready to find out how our button pressing events are visible for our system:

[user@dom0 ~]$ xinput test 14 |grep -v motion

If we pressing a button now we will see the event received by the Xorg system. The important part is the button numbers, what we should make a note after found all of them.

For the magic part we need the following two packages: The xbindkeys is a program that grab keys and mouse button events in X and  starts associated shell command. And the xdotool which lets you simulate keyboard input and mouse activity.

In case of Qubes OS the xbindkeys is not installed by default, so you have to install this package manually in dom0. Other Linux distribitions probably contains booth packages by default.

If you already have those packages, you only need to create a configuration file to make it work:

# Qubes secure_copy_sequence /etc/qubes/guid.conf
"xdotool keydown shift keydown ctrl key c keyup ctrl keyup shift"
 b:8
# Qubes secure_paste_sequence /etc/qubes/guid.conf
"xdotool keydown shift keydown ctrl key v keyup ctrl keyup shift"
 b:9

# KDE nextDesktop 
"qdbus-qt5 org.kde.KWin /KWin org.kde.KWin.nextDesktop"
 Mod4 + Super_L + b:7
# KDE previousDesktop
"qdbus-qt5 org.kde.KWin /KWin org.kde.KWin.previousDesktop"
 Mod4 + Super_L + b:6

The first example above shows how to bind the Qubes inter-vm copy paste key combination to a single mouse button. The second is KDE specific and lets you switch desktops with a specific mouse button + the windows key.

This way you can bind any action to a single mouse button. The only limit is your imagination :)

The xbindkey -k command gives you a great help about to identify your keyboard buttons. The following example shows how cans you refer to your “windows button” in the correct format you can use directly to your .xbindkeysrc file:

[user@dom0 ~]$ xbindkeys -k
Press combination of keys or/and click under the window.
You can use one of the two lines after "NoCommand"
in $HOME/.xbindkeysrc to bind a key.
"NoCommand"
 m:0x40 + c:133
 Mod4 + Super_L

You can find more about the tools used:

You can apply your just created configuration by restarting the xbindkeys service:

[user@dom0 ~]$ killall xbindkeys && xbindkey

It is a wise choice to start this process automatically. In case of KDE it is pretty straight forward: