12

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!

1 Answer 1

15

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

  1. 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
    
  2. 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)
    
  3. Delete the line starting with "xmodmap: up to 4..."

  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 Mode_switch from the mod5 line to mod3 line 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
    
  5. 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
    
  6. 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.

  7. 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 keycode specifies 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.

  8. Save the file and exit the editor.

  9. 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
    
  10. 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.

  1. Use xev to find the keycodes and keysyms

  2. 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 <code> <base> etc) with appropriate values.

  3. Backup the curkeys.map file.

  4. Open the curkeys.map and edit the line for the corresponding keycode.
  5. 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.

3
  • any luck with this one ? If this is not helping or in any way unclear pls comment, I will revise and make it more useful.
    – koushik
    Oct 14, 2010 at 8:14
  • 1
    Please note, that in Linux Mint 17 Xfce (or at least there), it has to be ~/.Xmodmap, ~/.xmodmap gets ignored.
    – zbr
    Sep 11, 2014 at 16:12
  • 2
    Don't forget to clear the keys that are being reset as per unix.stackexchange.com/a/4526/2512
    – Andy
    Nov 5, 2015 at 16:17

You must log in to answer this question.