Note: The following is written for Ubuntu 12.04 and KDE 4. Other distributions will behave similarly, and the described solution can be used for software other than KDE as well, but the specific details may differ in those cases. For more details, please refer to this article, which has been my primary source and describes the used tools in much more detail.
The issue
One of the features I’ve always particularly liked about KDE is the fact that you can assign (and reconfigure) keyboard shortcuts to pretty much anything. Once you’ve gotten used to pressing Ctrl+Alt+A to switch to the latest Window that requested focus (e.g. an instant message that arrived while you were typing an email), you’ll miss that feature on any system that doesn’t have it.
When KDE 4 first came out, its new composite desktop effects were all the rage. After a few release cycles they became stable enough to actually use them, too. But I soon realised that with all the cool looking new window switchers, I still preferred the classic list of icons with title labels for Alt-Tabbing through my desktop. Stuff like the Present Windows effect looked cool, but was pretty useless with my hands on the keyboard. And when I had my right hand on the mouse, I wasn’t keen on pressing some keyboard combination to trigger an effect to use with the mouse.
Modern power user mice have lots of buttons. So why not use those buttons as shortcuts to trigger certain actions? The problem is that KDE only knows about the three primary mouse buttons (plus the scroll wheel), supposedly due to limitations of the underlying QT libraries. Even though X11 has no problems recognising the additional buttons, KDE itself won’t handle them. And even if it did – it still doesn’t let you use mouse buttons as shortcuts. The shortcut configuration widget will only react to keyboard input.
Requirements
The clean solution would obviously be to simply have the shortcut configuration widget accept keyboard keys as well as mouse buttons (all of them), and other input events like gamepad buttons etc. as well. But as long as that’s not an option, we can simply trick X11 to produce arbitrary keyboard events when a specific mouse button is pressed.
In addition to the standard KDE installation, this solution requires two additional packages, xbindkeys and xautomation:
sudo apt-get install xbindkeys xautomation
xbindkeys provides a demon for translating keys (in our case: mouse button events) to actions (in our case: keyboard key combinations). When installed, the current Ubuntu version will start it automatically with X11/KDE.
Configuration
To define the mappings, xbindkeys uses a configuration file .xbindkeysrc in the user home directory. A template file can be created easily:
xbindkeys --defaults > ~/.xbindkeysrc
We can now edit this file to bind mouse buttons to key combinations. The default template file already contains a few example mappings which should make the syntax quite clear: The first line of each mapping defines the action to execute, the second (indented) line specifies which event should trigger the action. A blank line completes the mapping. Any text after a hash character (#) is a comment and will be ignored by the demon.
The xte tool from the xautomation package can be used to produce key combination event sequences. For example, the following command line will have the same effect as a user pressing the F1 key:
xte "key A"
There is another tool that can be used to determine the mouse button IDs. Running xev will open a small window which listens to mouse events and logs them to the console. Simply pressing a mouse button in that window will produce a log message showing the button’s ID.
My Logitech mouse has two buttons which by default are recognised as back and forward actions by browsers. I never use them to trigger these actions (I usually use Alt+Left and Alt+Right), so I want to map them to something else. KDE’s Desktop Grid and Present Windows switchers are neat effects which I would like to trigger via these buttons. The default shortcuts for these effects are Ctrl+F8 and Ctrl+F9.
The following lines will map mouse button 8 to Ctrl+F9 and mouse button 9 to Ctrl+F8:
# Bind "back" mouse button to Ctrl+F8 "xte 'keydown Control_L' 'key F8' 'keyup Control_L'" b:9 # Bind "forward" mouse button to Ctrl+F9 "xte 'keydown Control_L' 'key F9' 'keyup Control_L'" b:8
To make xbindkeys re-read the configuration file without restarting the X server, simply execute this:
killall xbindkeys && xbindkeys
Voilà: Desktop Grid and Present Windows at your fingertips!
More features
Different mappings can easily be derived from these lines. For example, if you’re not using the left/right tilt clicks of your mouse wheel for horizontal scrolling, you could map buttons 6 and 7 to actions of your choice.
Instead of mapping the mouse buttons directly to the configured keyboard shortcuts, you could alternatively map them to rather obscure key combinations like the following:
# Bind "scroll right" mouse wheel click to Super+Home "xte 'keydown Super_L' 'key Home' 'keyup Super_L'" b:7
You can then use KDE’s standard keyboard shortcut configuration dialogues to bind the mouse buttons to actions by pressing a mouse button over the desired shortcut configuration widget. This will enter the bound key combination to the selected action.
Thanks! Workes like a charm (-:
Your example works beautifully.
I have remapped my keyboard with xmodmap such that by pressing “Mode_switch” (remapped to “Window_key”) together with either h | j | k | l it gives me Left, Down, Up and Right (the vi-mapping). On my lenovo X230 the mouse buttons for the track-point are very conveniently located under my thumbs at rest. So what I would really like is something like this:
“xte ‘keydown Mode_switch’ ‘key ‘ ‘keyup Mode_switch'”
b:2
Is there a way to do this? I have tried xbindkeys with xvkbd, xdotools etc to no avail.
thanks
the example line above should read:
“xte ‘keydown Mode_switch’ ‘key any_key’ ‘keyup Mode_switch'”
Pingback: Mapping KDE actions to extra mouse buttons | Marian Schedenig's Website - jpollock
Exactly what I have been looking for since switching to KDE from OSX (and never looking back)! Thank you for outlining this in such detail
Thanks for this! Now I can setup my forward/back buttons to copy/paste.
i am trying to use my forward and backward buttons for horizontal scrolling but no use. this is the code:
(xbindkey ‘(“b:8”)’ “xte ‘keydown Shift_L’ ‘mouseclick 4’ ‘keyup Shift_L'”)
but no use. Any help, please.
I have also tried
(xbindkey ‘(“b:8”) “xte ‘mouseclick 6′”)
but, no use.
I prepared a little ready-to-use config under https://github.com/wiswedel/mouseButtonBindings.
Feel free to fork and modify for your usecases and mice.
I’m sorry, it’s a very interesting program, but it absolutely not working. I try it in OpenSuse 15.2 (KDE). It not trap anything or maybe a trap events but not send command xte. Do you have any recipe for me?