I'm a Ubuntu 10.04 user who is looking for a way to, for example, make my computer type a "+" character when I hold down the Windows Key (I think it's called Super in Linux world) and press the K key. I need this to work in all applications. (I'm a person with a typing disability, and I need to adapt Ubuntu to my needs.) Thanks!
Since you want to remap the keys for all applications the best option is to use xmodmap. It is flexible and very powerful but involves typing in a few commands into a terminal.
Step 0 - The approach
The X-server manages the keyboard and all key events and translates that into keycodes for all applications.
The approach would be to map a modifier key (like Super or Right Alt key) as the "mode switch" key and tell the X-server to generate different codes depending on whether a key is pressed with Mode key being held down or not.
By default there is no mode switch key defined and also all keys are configured to generate the same code when they are pressed with or without mode switch. This is good since this means except for the keys you override explicitly no other keys will behave differently or need additional configuration.
However, I would like you to consider using Right Alt key as mode switch especially if you are also using compiz since some compiz plugins map super key shortcuts (e.g., window picker, shift switcher etc). If you are not keen on controlling compiz via the keyboard then Super is just fine.
To xmodmap, the super keys are identified as Super_L or Super_R. You need to pick one to use as the mode switch key. Alternatively, the right alt key is Alt_R. You can confirm these by running xev and pressing the necessary keys on your keyboard. See this post for the steps.
Step 1 - Setting up the modifier map
Open a terminal (
Applications -> Accesories -> Terminal) and run the following command to create a file with current keybindings. We will use this as starting point.
xmodmap -pke > curkeys.map xmodmap -pm >> curkeys.map
Open this in your favourite text editor.
gedit curkeys.map &opens it in gedit. Towards the end of the file, you will see some lines like this:
keycode 253 = keycode 254 = keycode 255 = xmodmap: up to 4 keys per modifier, (keycodes in parentheses): shift Shift_L (0x32), Shift_R (0x3e) lock Caps_Lock (0x42) control Control_L (0x25), Control_R (0x69) mod1 Alt_L (0x40), Alt_R (0x6c), Meta_L (0xcd) mod2 Num_Lock (0x4d) mod3 mod4 Super_L (0x85), Super_R (0x86), Super_L (0xce), Hyper_L (0xcf) mod5 ISO_Level3_Shift (0x5c), Mode_switch (0xcb)
Delete the line starting with "xmodmap: up to 4..."
Edit the modifier map so it looks like this. Put the word "add " at the beginning of each line and insert "= " after the modifier name. Then remove the codes in parentheses and commas. Also note that I have moved
mod3line since it was empty. The modified table should look like this - actual contents will slightly vary in your case from those below (depends on your keyboard layout).
add shift = Shift_L Shift_R add lock = Caps_Lock add control = Control_L Control_R add mod1 = Alt_L Meta_L Alt_R add mod2 = Num_Lock add mod3 = Mode_switch add mod4 = Super_L Super_R Super_L Hyper_L add mod5 = ISO_Level3_Shift
Remap physical mode-switch key. Add a line like this at the end (Replace Super_L with Super_R or Alt_R if required).
keysym Super_L = Mode_switch
Remove the keyname (Super_L) from any modifier definition. For Super_L this means removing it from the mod4 line.
add mod4 = Super_R Hyper_L
Now the right "Super" key will still act as a normal super key whereas the left key will have special properties.
Now we need to remap the keys to produce different codes whether they are pressed while holding down Super_L or not. Each line in our file beginning with
keycodespecifies 4 keysyms for each key to be generated based on whether Mod1 (shift keys) and Mode switch keys are pressed.(link)
!........................................................................... ! Key Base Shift Mode Mode+Shift !--------------------------------------------------------------------------- keycode 13 = 4 dollar 4 quotedbl keycode 14 = 5 percent 5 colon keycode 15 = 6 asciicircum 6 comma keycode 16 = 7 ampersand 7 period ... keycode 45 = k K k K
If we want Super_L+k keypress to generate a "+" key then we need to modify it to read so
keycode 45 = k K plus plus
The final plus also maps Shift+Super_L+k to plus, but this can be mapped to something else. For each key there is exactly 1 line to modify. Edit more lines to remap more keys - leave the first 2 entries intact to retain normal keypress behaviour.
Save the file and exit the editor.
Install the keymap by running the following commands in a terminal. The first one sets it up for this session, the second makes it permanent for future sessions.
xmodmap curkeys.map cp curkeys.map ~/.Xmodmap
You can immediately test this by pressing the modified keys (Super_L + k for example).
Step 3 - Adding / revising the map
Once the modified map is installed it is easy to add new keys.
Use xev to find the keycodes and keysyms
test it by running this command to map the key :
xmodmap -e "keycode <code> = <base> <shift> <new-mapping> <new-shift-mapping>"
Replace items in angle brackets (like
<base>etc) with appropriate values.
- Open the
curkeys.mapand edit the line for the corresponding keycode.
Reapply with the below commands (first one is not necessary if you did step 2)
xmodmap curkeys.map cp curkeys.map ~/.Xmodmap
Note:1: Modifications made in Keyboard Shortcuts (via e.g.,
System -> Preferences -> Keyboard Shortcuts) affect the modifier map and will be generally lost on next login. So please avoid that.
Note:2: I sometimes get error messages like this while using this method. I don't know what this means, however, these are generally harmless.
X Error of failed request: BadValue (integer parameter out of range for operation) Major opcode of failed request: 118 (X_SetModifierMapping) Value in failed request: 0x17 Serial number of failed request: 263 Current serial number in output stream: 263
Detailed help for xmodmap is available here.