Keyboard hotkeys

We've all seen those keyboards that come with row upon row of extra buttons - the ones that promise lots of extra functionality, but so rarely live up to that promise.

Well, maybe that's the case on some OSes, but it needn't be with Linux!

All you need to get these keys working are:

To start with, open up an xterm and run "xev". A little white box with a black square in it will appear, and a load of text will appear in the xterm.

Put your mouse cursor onto the xev window, and the text will go crazy as you move the mouse. This is because every mouse movement is being reported to the xterm.

Leave the mouse alone and press a few buttons. For example, press "a"

KeyPress event, serial 32, synthetic NO, window 0xa00001,
root 0x8e, subw 0x0, time 1418934, (77,117), root:(674,531),
state 0x0, keycode 38 (keysym 0x61, a), same_screen YES,
XLookupString gives 1 bytes: (61) "a"
XmbLookupString gives 1 bytes: (61) "a"
XFilterEvent returns: False

KeyRelease event, serial 32, synthetic NO, window 0xa00001,
root 0x8e, subw 0x0, time 1419038, (77,117), root:(674,531),
state 0x0, keycode 38 (keysym 0x61, a), same_screen YES,
XLookupString gives 1 bytes: (61) "a"

This tells you everything there is to know about the "a" key. As you can see, it generated two events, one for when you pressed the key, and one for when you released it. But the thing we're really interested in is the "keycode" bit - each key has a unique keycode. When you press "a", your keyboard doesn't actually tell your PC 'The "a" key was pressed!'. No, it says 'Key 38 was pressed!'. Your PC then translates "keycode 38" into "a".

Now, assuming you have a Microsoft-friendly keyboard, you probably have at least one button with the Windows logo on it. See what xev makes of this. Usually, it's keycode 115.

And keycode 115 is usually unassigned. Hence a useless key on Linux. Until now!

Go through all the "special" keys on your computer and find their keycodes. Note them all down, either on paper or in a text editor. Once you've got every keycode, we're done with xev - shut it down.

We now move on to xmodmap. As the man page explains, this is a utility for modifying keymaps and pointer button mappings in X. In other words, this is what we use to turn keycodes into recognised keys.

Xmodmap is usually run by the Xsession script that starts X. You don't want to use the command yourself, just create a file that contains all the keycodes you want used. Xsession will do all the rest of the work.

Check your Xsession file to make sure you put your Xmodmap file in the right place. For me, it's /etc/X11/xinit/.Xmodmap. You'll need to be root to create this file. With your favourite text editor, open the file and start assigning keycodes to names.

When I first assigned keycodes, for an easy life, I just assigned the special keys to Function keys - I have 12 actual F-keys, but you can assign plenty more, so I made my Windows-logo key F13. However, when you've got nearly two dozen special keys, this can get confusing. So if you're assigning more than just a few special keys, use descriptive names. For example, my Xmodmap file uses:

keycode 115 = SLstart
keycode 116 = SRstart
keycode 117 = Smenu

keycode 234 = Sback
keycode 233 = Sforward
keycode 232 = Sstop
keycode 231 = Srefresh
keycode 122 = Ssearch
keycode 230 = Sfavourites
keycode 130 = Swebhome
keycode 236 = Smail
keycode 160 = Smute
keycode 174 = Svolumedown
keycode 176 = Svolumeup
keycode 162 = Splaypause
keycode 164 = Sstop
keycode 144 = Sprevtrack
keycode 153 = Snexttrack
keycode 129 = Smedia
keycode 198 = Smycomputer
keycode 161 = Scalculator
keycode 223 = Ssleep

The "S" stands for "Special key", then we have the button description. In order, we have the left Windows-logo key, the right Windows-logo key, the "menu" key next to the right Windows-logo key, and then all the special keys.

Now this is all very well, but X doesn't actually know what any of those names mean. You need to tell it about these names. This is the extra step you have to put in for not using existing names like "F13"

We find out about the keys X knows about by looking at the file /usr/X11R6/lib/X11/XKeysymDB. You can either assign keycodes to the existing names in here, or add new names of your own devising.

For instance, you'll probably see an entry named "XF86Start". You could assign keycode 115 to "XF86start" and everything would work fine. Alternatively, you could do as I did, and add new key names to the bottom of this file. Any name you like, followed by a unique identifier. Here are my entries:
SLstart :11000001
SRstart :11000002
Smenu :11000003
Sback :11000004
Sforward :11000005
Sstop :11000006
Srefresh :11000007
Ssearch :11000008
Sfavourites :11000009
Swebhome :1100000A
Smail :1100000B
Smute :1100000C
Svolumedown :1100000D
Svolumeup :1100000E
Splaypause :1100000F
Sstop :11000010
Sprevtrack :11000011
Snexttrack :11000012
Smedia :11000013
Smycomputer :11000014
Scalculator :11000015
Ssleep :11000016

Yes, I could have used existing names, but I preferred to have a uniform naming scheme.

So, once you've edited the Xmodmap file to point to key names listed in the XKeysymDB file, you're mostly done. All your keys are now recogniseable to X. It's time to assign some functionality to them.

Exactly how you do this depends on your Window Manager, so I can't help here. However, in FVWM2, which is what I use, it's fairly simple. From my config file:
Key name Context Modifier Action
Key SLstart A A Popup "Utilities"
Key SRstart A A Menu "Window Ops" Nop
Key Smenu A A WindowList
Key Sback A A Exec $HOME/.fvwm/scripts/mozillaback
Key Sforward A A Exec $HOME/.fvwm/scripts/mozillaforward
Key Sstop A A Exec $HOME/.fvwm/scripts/mozillastop
Key Srefresh A A Exec $HOME/.fvwm/scripts/mozillarefresh
Key Ssearch A A Exec $HOME/.fvwm/scripts/mozillasearch
Key Sfavourites A A Exec $HOME/.fvwm/scripts/mozillafaves
Key Swebhome A A Exec $HOME/.fvwm/scripts/mozillahome
Key Smail A A Exec $HOME/.fvwm/scripts/mail
Key Smute A A Exec $HOME/.fvwm/scripts/mute
Key Svolumedown A A Exec $HOME/.fvwm/scripts/voldown
Key Svolumeup A A Exec $HOME/.fvwm/scripts/volup
Key Splaypause A A Exec $HOME/.fvwm/scripts/xmmsplay
Key Sstop A A Exec $HOME/.fvwm/scripts/xmmsstop
Key Sprevtrack A A Exec $HOME/.fvwm/scripts/xmmsprev
Key Snexttrack A A Exec $HOME/.fvwm/scripts/xmmsnext
Key Smedia A A Popup "Media"
Key Smycomputer A A Exec $HOME/.fvwm/scripts/mycomputer
Key Scalculator A A Exec $HOME/.fvwm/scripts/calculator
Key Ssleep A A Exec $HOME/.fvwm/scripts/sleep

Context means where you happen to be - "W" would mean a Window-specific action, while "A" means "anywhere". Modifier refers to the Ctrl and Alt keys, neither of which are really wanted for special keys, at least for me. And then there's the action. Mostly, these run simple shell scripts in my FVWM2 script directory. Each time I press a key, they run these scripts.

A few samples of how they work:

Firefox is my browser, and it can be controlled from the command line via the "remote" option. So to go back and forth through the history, I use the commands:

firefox -remote "openURL(javascript:history.go(-1);)"
firefox -remote "openURL(javascript:history.go(1);)"

To go to a search page:

firefox -remote "openURL(http://www.google.co.uk)"

Simple, huh?

Volume control is similarly easy, at least if you use Alsa:

amixer set Master 2-%
amixer set Master 2+%
amixer set Master toggle

turn the master volume down or up by 2% at a time, or mute/unmute it altogether

To control my main music player, XMMS, I use

xmms --fwd
xmms -r
xmms -t
xmms -s

To go forward, back, Play/Pause, and stop respectively.

Calculator is simply set to run xcalc, and Sleep turns on my screensaver using the command xscreensaver-command -activate

And that's pretty much everything explained: How to create a key name, how to assign a keycode to that name, and how to use simple shell scripts to give you control over various applications. The only thing I can't be specific about is how to assign keys to shell scripts, because that's sadly highly variable. But I hope that what I have been able to tell you will be enough to get you going.

Creative Commons License

Unless otherwise stated, all articles/files on this website are licensed under a Creative Commons License. This page's URL must be supplied in attribution.