How can I change what keys on my keyboard do? (How can I create custom keyboard commands/shortcuts?)

I want to change the key bindings on some of the keys on my keyboard. I want some to run commands and others to activate different keys.

What applications can I use to do this?


Index:

  • Xbindkeys

  • Default keyboard and shortcut settings (from within System Settings)

  • Xmodmap

  • Xkeycaps

  • Autokey

  • xkb

I'm still looking for answers using dconf and any other method.


xbindkeys..

sudo apt-get install xbindkeys

Xbindkeys is a very versatile program that lets you remap keys very easily. It uses a config file, my default located in your home directory, to change key bindings into certain commands.

To create a default config file you use the command:

xbindkeys --defaults

Which prints the default config file. So if you want to create the file containing the default values you would use:

xbindkeys --defaults > $HOME/.xbindkeysrc

Which prints the default values into a hidden file named .xbindkeysrc located in home (~).

Now to actually change the bindings of keys we first need to know what the name or keysym of those keys is. xbindkeys allows us to use the -k handle to find the name of a key or key combination. Run:

xbindkeys -k

And press a key or key combination. Your output will look something similar to this (when pressing space):

"NoCommand"
m:0x10 + c:65
Mod2 + space

"No Command" tells us that currently no command is associated with the Space key.

m:0x10 + c:65
Mod2 + space  

Is the name of the key/key combination.

the config file..

Lets open up the config file you made earlier:

gedit .xbindkeysrc  

Here is an excerpt from the default config file:

#
# A list of keys is in /usr/include/X11/keysym.h and in
# /usr/include/X11/keysymdef.h
# The XK_ is not needed.
#
# List of modifier:
#   Release, Control, Shift, Mod1 (Alt), Mod2 (NumLock),
#   Mod3 (CapsLock), Mod4, Mod5 (Scroll). 
#

# The release modifier is not a standard X modifier, but you can  
# use it if you want to catch release events instead of press events

# By defaults, xbindkeys does not pay attention with the modifiers
# NumLock, CapsLock and ScrollLock.
# Uncomment the lines above if you want to pay attention to them.

#keystate_numlock = enable
#keystate_capslock = enable
#keystate_scrolllock= enable

# Examples of commands:

"xbindkeys_show" 
 control+shift + q  

Every line beginning with # is a comment and won't be read or run by xbindkeys.

So far the only line that isn't commented out is:

"xbindkeys_show" 
 control+shift + q  

This excerpt shows the basic syntax of xbindkeys commands:

"Command to run (in quotes)"
key to associate with command (no quotes)  

So as you can see:

"xbindkeys_show" 
 control+shift + q  

Runs the command xbindkeys_show when you press Ctrl+Shift+q.

bind keys to commands..

Now lets try binding a few keys. I recommend clearing the entire default file so that it's blank. It contains preset key bindings you probably don't want.

Now lets say you want to use Ctrl+b to open your browser. First you need to know what the name or keysym of Ctrl+b is. As mentioned earlier you can use xbindkeys -k to find the name of a key or keys, but there is an easier way. For simple combinations like Ctrl+b you can just use:

Control+b

A lot easier isn't it!

Now find the command for your favorite browser:

  • For Firefox: firefox

  • For Chromium: chromium-browser

  • For Opera: opera

Remember the syntax from earlier? The xbindkeys command to launch Firefox (or your other favorite browser) when you press Ctrl+b is:

"firefox"
Control+b

Now put that in your config file and save it. Now you might notice your command doesn't work yet, that's because xbindkeys isn't running. To start it just run xbindkeys from a terminal. Your Ctrl+b should now start your browser!

bind keys to other keys..

If you want a key on your keyboard to call a different key on your keyboard, you will need an extra piece of software as xbindkeys does not support this on it's own. I know of two programs which we can use, xdotool and xte. I prefer xte so I'm going to use that.

Install it:

sudo apt-get install xautomation

The syntax for xte is like this:

xte 'command key/mousebutton/xyCoordinates'

Examples:

  • To call a single key press: xte 'key keyName'

  • To call a key combination: xte 'keydown keyName' 'keydown secondKeyName' 'keyup keyName' 'keyup secondKeyName

  • To call a mouse button: xte 'mouseclick buttonNumber' (We'll discuss finding button numbers a little latter)

  • To move the mouse: xte 'mousemove xCoordinate yCoordinate'

  • And more! Read man xte

Now that you know the command for simulating key presses you can call it from your xbindkeys script, like this:

"xte 'key b'"
Control+b  

As you might guess, this calls xte 'key b' when we press Ctrl+b, which would enter a b into any document you might be currently working on.

I thing to note however is that xbindkeys and xte don't always work very well together. Sometimes you have to press the keys exactly at the same time to get output, other times it works just fine. This may or may not have to do with system configuration and/or hardware.. I'm not sure. See maggotbrain's answer for a more reliable way of binding keys to other keys.

bind mouse buttons to commands..

You can also use xbindkeys to bind mouse buttons to commands (and thence keyboard shortcuts, see above). The basic format for mouse buttons should be familiar to you now:

" [command to run]  "
b:n

Where [command to run] is the command you want to run and n the number of the mouse button you want to use for that command.

If you don't know the number of your mouse button you can use xev to find out what it is:

xev | grep button

The output will be something like this:

user@host:~$ xev | grep button
    state 0x10, button 1, same_screen YES
    state 0x110, button 1, same_screen YES
    state 0x10, button 2, same_screen YES
    state 0x210, button 2, same_screen YES
    state 0x10, button 3, same_screen YES
    state 0x410, button 3, same_screen YES

When I press each of my mouse buttons.

For example:

" firefox "
b:2

Launches firefox when I press my middle mouse button.


Xev and xmodmap

Changing key bindings using xev and xmodmap.

Both command line applications are available by default, so there is no need to install additional software.

Xev "creates a window and then asks the X server to send it events whenever anything happens to the window (such as it being moved, resized, typed in, clicked in, etc.)." xev man page

xmodmap is a "program is used to edit and display the keyboard modifier map and keymap table that are used by client applications to convert event keycodes into keysyms." xmodmap man page

The following example will remap the Caps_Lock key to the behavior of the Esc key (Many vi/vim users find this to be a useful keyboard mapping).

Using xev

Start the xev application from a terminal window (Ctrl-Alt-t). It may be useful to grep its output like xev | grep -i key

The application will initialize, display a number of lines, and start a small window with a box. Keep the xev application window in focus, and press the key whose properties/behavior that you wish to use.

  • Press the ESC key

In the terminal window, you will see several lines of output. Make note of 3rd line returned. This will contain the name of the property you wish to move to the other key.

KeyPress event, serial 32, synthetic NO, window 0x3e00001,
    root 0x256, subw 0x0, time 16245388, (616,73), root:(1487,535),
    state 0x10, keycode 9 (keysym 0xff1b, Escape), same_screen YES,
    XLookupString gives 1 bytes: (1b) ""

In this case, the Esc key(keycode 9) uses the name "Escape".

  • Press the Caps Lock key

This time we are looking for the keycode that Caps Lock is using.

Again, note the 3rd line:

KeyRelease event, serial 32, synthetic NO, window 0x4c00001,
    root 0x256, subw 0x0, time 94702774, (862,151), root:(1733,613),
    state 0x10, keycode 66 (keysym 0xffe5, Caps_Lock), same_screen YES,
    XKeysymToKeycode returns keycode: 9
    XLookupString gives 1 bytes: (1b) ""

Using xmodmap

Now that we have obtained the information on the keys that we wish to change from xev, we will use xmodmap to modify the keymaps. From the command terminal (Ctrl+Alt+t), run the following commands:

  • This command modifies the Caps Lock to use the same behavior as Esc

     xmodmap -e "keycode 66 = Escape"
    

You can also remap it to basically any key, here it is remapped to the p key

    xmodmap -e "keycode 66 = p"
  • This option prints the current keymap table as expressions into the file ~/.Xmodmap

     xmodmap -pke > ~/.Xmodmap
    

Activate the changes(for this login session only) with following command:

xmodmap ~/.Xmodmap

Making changes persistent across reboots:

  • If it doesn't exist, create a file in your home folder called .xinitrc.

      touch ~/.xinitrc
    
  • Place the following line in the file and save the file:

      xmodmap ~/.Xmodmap
    

Modifying keys with different state behaviors

(such as Num Lock)

  • Obtain the keymap table for the modifier keys (output abbreviated here)

      $ xmodmap -pm
      shift       Shift_L (0x32),  Shift_R (0x3e)
      mod2        Num_Lock (0x4d)
    

If you wanted to change, for example, the behavior of the period on Del/Period key on the number keypad, to a comma, use the following command:

xmodmap -e "keycode 91 mod2 = KP_Delete comma"

Note that this is using mod2 keymapping to change key behavior when the modifier Num Lock is pressed. The syntax for this is:

xmodmap -e "<KEYCODE> <MODIFIER> = <behaviour> <behaviour_with_modifier>"

Resource