283

I'm searching for a way to remap certain keys in ubuntu.

i.e.

I'd like to change PgUp to Home or PgDown to End.

Does a built-in command or a tool exist reassign keys in Ubuntu/GNOME?

4
  • 1
    checkout my answer here. It doesn't worth copy and paste same answer. Perhaps it would help you. Jun 2, 2012 at 9:40
  • 2
    Any Emacs-like bindings here for CTRL-P/N for unit steps? Jul 7, 2015 at 13:12
  • 2
    Since some time xmodmap is depricated! to get a system wide setting you have to use xkb. So edit the language file in /usr/share/X11/xkb/symbols/ to add your changes there. See askubuntu.com/a/898462/34298
    – rubo77
    Mar 30, 2017 at 21:48
  • If you want to remap your keyboard keys or mouse buttons to certain keys, use "Input Remapper" by sezanzeb. It's VERY simple, it has a GUI, and it just WORKS. I just have set a certain shortcut to simulate a keyboard key, works well.
    – Allexj
    Jan 7, 2023 at 12:54

11 Answers 11

291

Notice: As of 2013, Ubuntu and derivatives no longer use xmodmap, but instead use xkb. For more information see this answer. The answer below is no longer relevant for current releases.


For remapping certain keys you need two tools. First xev (command-line tool) and second xmodmap (also command-line tool). Both should be available in Ubuntu without extra installing them.

  1. Start terminal window and run xev. Now it's active and waits for you to press a key. Then press the key whose behaviour you want to change. i.e. PgUp.

  2. xev will output some information about the pressed key. The third line is important. It should look similar to:

     state 0x10, keycode 110 (keysym 0xff55, Prior), same_screen YES,
    

    in this example Prior is the name of the behaviour the key is assigned to at the moment, the number keycode is the internal id to recognize the key. Now do this with another key i.e. PgDown give this output

     state 0x10, keycode 115 (keysym 0xff56, Next), same_screen YES,
    

    Here again the interesting part for us is keycode 115 and Next - the name of the behaviour.

  3. now when you want to swap the two keys use xmodmap.

      xmodmap -e "keycode 110 = Next"
    

    This changes the key with keycode 110 on your keyboard to the action Next. It's pretty simple.

    Note that if the key you are mapping should have a different meaning when used with the Shift key (for example for British keyboard layouts, Shift+2 gives quotation marks) then you can simply list the secondary command after the first. For example if you want the key with code 53 to map to backslash normally, but to the bar symbol when used with shift, you might do:

      xmodmap -e "keycode 53 = backslash bar"
    

Additional information: The sequence of these mappings depends on the keyboard layout. It usually is Key, Shift+Key, mode_switch+Key, mode_switch+Shift+Key, AltGr+Key, AltGr+Shift+Key, but can be very different for more special layouts, like in case of the German Neo 2 one. To skip a column use NoSymbol. Here is a comprehensive list of all keysyms.
You can see the concrete sequence for your layout by finding it in one of the files in /usr/share/X11/xkb/symbols/.

Note: These change are for the active X session only and will be lost after reboot. When you want to save the changes permanently you have to run the following commands after the ones above:

xmodmap -pke >~/.Xmodmap

(it creates a file named .Xmodmap in your home directory (~))

Then you have to create a file named .xinitrc in your home directory where you put command xmodmap .Xmodmap in.

You can now modify .Xmodmap and run xmodmap .Xmodmap from console to see the changes immediately. The changes in .Xmodmap will persist.

source: Ubuntu Foruns

Bonus stuff:

If the key you are remapping has different behavior depending on a state ( like how the keys in the numeric keyboard depend on NumLock) you simply have to do xmodmap -pm to get a list of modifiers and then do:

xmodmap -e "KEYCODE MODIFIER = behaviour behaviour_with_modifier"

Suppose, for example, that you want to get a period instead of a comma on the numeric keyboard (useful for most programmers), but you want to keep the "delete" behavior when NumLock is off.

xmodmap -e "keycode 91 mod2 = KP_Delete period"

mod2, because xmodmap -pm tells us that mod2 is Num_Lock, the other names are obtained by pressing the keys in xev.

15
  • 6
    xev is not able to catch Fn key pressings
    – om-nom-nom
    Feb 15, 2012 at 15:08
  • 3
    The selected answer didn't work for remapping the Caps-lock key for me on Ubuntu 12.10. I was able to to do this by going to System Settings -> Keyboard -> Layout Settings -> Options, which has a list of keys and alternative behaviors. Worked flawlessly in Unity and terminal. Oct 10, 2012 at 19:17
  • 1
    If you have multiple keyboards connected, will these tools see a difference between the same key on another keyboard?
    – jobukkit
    Jun 27, 2013 at 17:10
  • 1
    Strange, I did everything, but my keymappings still reset after restarting. Dec 27, 2013 at 3:39
  • 1
    I don't think I have an -event flag in Ubuntu 12.04. It throws an error and doesn't mention "event" in man xev. Feb 17, 2014 at 14:47
27

If you're trying to move a Shift key, there are a few extra steps:

 xmodmap -e "keycode 62 = Up" # Shift => Up
 xmodmap -e "keycode 111 = Shift_R" # Up => Shift
 xmodmap -e "add shift = Shift_R" # Make the new Shift key actually do shifting
 xmodmap -e "remove shift = Up" # Prevent the old Shift key from shifting
 xset r 62 # Make the new Up key autorepeat
 xset -r 111 # Prevent the new Shift key from autorepeating
3
  • +1 The most unix-y answer of all of those for a modifier (I had already done so way, way back with my iBook 2, when I wanted the enter key to have the function of Control_R, but had forgotten the details).
    – rbrito
    Jan 6, 2013 at 8:47
  • 3
    An important answer for users using keyboards on Lenovo Laptops May 1, 2017 at 15:38
  • Since xmodmap is specifically programed to allow modifier key swappings, according to the man page, this should be doable atomically.
    – anon
    Aug 17, 2022 at 18:34
16

I've just had an afterthought.. I think you may mean something entirely different by "remap".. but I'll leave my answer as it is... (I don't know how to re-assign one key to behave as another)

UPDATE: my 'afterthought' has been confirmed; ( I've answered the wrong question :)... please see NES's Community Wiki answer (accepted above).

There are two general ways to remap rebind a key.

  • locally to a particular program
    (a key can be used for different things in different apps/windows)
  • globally for a specific user
    (a key has the same function in all windows)

For 'local to a program' methods, there is sometimes a way to change keybindings offered by the app itself... eg.

Firefox has an addon called keyconfig ... for some info see this MozillZine post

Most Ubuntu programs are Gnome based and there is a specific utility to modify the keybinding for any menu item of these Gnome apps... It is called Editable Menu Accelerator ... It is a very 'touchy' tool, but quite powerful.. You can enable it by running gconf-editor (via Terminal or Alt+F2)... navigate to desktop--gnome--interface and select can_change_accels .... You can then change menu items to virtual anything you like (per program/window)... I suggest you disable it as soon as you've done what you need..

Otherwise you can set up Global hotkeys. I use a program called xbindkeys Install xbindkeys, and there is also an option available via the Main Menu -- Preferences, called Keyboard Shortcuts

If you use xbindkeys, you will need to add it to your "Startup Applications" (Main Menu -- Preferences) ... Also (as suggested by Stefano Palazzo) I have previously written a more detailed description of xbindkeys in an answer on this askubuntu page

6
  • +1, very nice! A suggestion: You should integrate your great answer from another question into this one, maybe also explain the configuration format of xbindkeys a little bit. Feb 5, 2011 at 14:17
  • 1
    The bit about assigning other keys could be handled by xdotool, check out the man page, I've used it to solve this problem. Feb 5, 2011 at 14:24
  • i recently found another approach with a tool called xmodmap in combination with a tool called xev. i don't know what the differences between xmodmap and xbindkeys are, but this works pretty well for me. some advice with tool to prefer of the named two? Here is a very helpful step by step guide which describes xmodmap and xev ubuntuforums.org/showpost.php?p=7675138&postcount=2
    – NES
    Feb 5, 2011 at 14:28
  • @NES.. It appears I've addressed the wrong point.. You seem to want to actually remap the way a particular key is interpreted by the OS, ie, a non-standard keyboard interpretation, whereas I've been refering to a standard keyboard-interpretation, and simply overloading the default key-assignments. (I think what you are after is similar to swapping the left and right mouse buttons) .. Well it seems my answer was good for the wrong thing :)
    – Peter.O
    Feb 5, 2011 at 14:52
  • yes, but no problem. the answer is also interesting. the step by step guide i posted the link above was the right way. so i'll post a short answer with the solution that other users have a good guide. thanks fred
    – NES
    Feb 5, 2011 at 15:42
12

Here is how I tried to switch the mapping of the ENTER key to the SHIFT key (and vice versa):

$ uname -a

REPORTS:

Linux box 2.6.32-37-generic #81-Ubuntu SMP Fri Dec 2 20:35:14 UTC 2011 i686 GNU/Linux

$ which xmodmap

REPORTS:

/usr/bin/xmodmap

$ which xev

REPORTS:

/usr/bin/xev

$ xev

(ignore the next fifty lines or so)

PRESS THE ENTER KEY (notice the third line):
KeyPress event, serial 33, synthetic NO, window 0x5600001,
    root 0x110, subw 0x0, time 263441120, (738,242), root:(771,314),
    state 0x0, keycode 36 (keysym 0xff0d, Return), same_screen YES,
    XLookupString gives 1 bytes: (0d)
    XmbLookupString gives 1 bytes: (0d)
    XFilterEvent returns: False

KeyRelease event, serial 33, synthetic NO, window 0x5600001,
    root 0x110, subw 0x0, time 263441271, (738,242), root:(771,314),
    state 0x0, keycode 36 (keysym 0xff0d, Return), same_screen YES,
    XLookupString gives 1 bytes: (0d)
    XFilterEvent returns: False

PRESS THE SHIFT KEY (notice the third line):
KeyPress event, serial 30, synthetic NO, window 0x5600001,
    root 0x110, subw 0x0, time 263592202, (464,368), root:(497,440),
    state 0x0, keycode 62 (keysym 0xffe2, Shift_R), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False

KeyRelease event, serial 33, synthetic NO, window 0x5600001,
    root 0x110, subw 0x0, time 263592298, (464,368), root:(497,440),
    state 0x1, keycode 62 (keysym 0xffe2, Shift_R), same_screen YES,
    XLookupString gives 0 bytes:
    XFilterEvent returns: False

What's important is the third line of each keypress:

FOR:
state 0x0, keycode 36 (keysym 0xff0d, Return), same_screen YES,
The name "Return" is the name of the behavior of the key pressed.
The number of the key pressed is "36".

state 0x0, keycode 62 (keysym 0xffe2, Shift_R), same_screen YES,
The name "Shift_R" is the name of the behavior of the key pressed.
The number of the key pressed is "62".

REVERSE THE MAPPING:

$ xmodmap -e "keycode 62 = Return"
$ xmodmap -e "keycode 36 = Shift_R"

SAVE THE RESULTS:

$ xmodmap -pke > ~/.Xmodmap
$ vi ~/.xinitrc

ADD

 xmodmap ~/.Xmodmap

$ sudo reboot

The main problem was that the reversal did NOT work. The ENTER key was mapped to the SHIFT_R key; but the SHIFT_R key was not mapped to the ENTER key. Go figure.

8

In order to do global remaps independently of X, you can make use of console-setup(5) instead.

In my case I wanted to remap Caps Lock key to D, since my D-key is broken :)

First I used dumpkeys(1) to get a template for a mapping, in the case of the D-key, the interesting bit is the mapping for keycode 32 (on my keyboard); Note that there are two spaces in the grep pattern!

$ sudo dumpkeys | grep "keycode  32" > tempfile
$ cat tempfile
keycode  32 = +d
    shift   keycode  32 = +D
    altgr   keycode  32 = +eth
    shift   altgr   keycode  32 = +ETH
    control keycode  32 = Control_d
    shift   control keycode  32 = Control_d
    altgr   control keycode  32 = Control_d
    shift   altgr   control keycode  32 = Control_d
(121 lines total...)

In order to change the map to apply to Caps Lock (keycode 58 on my keyboard) instead

sed 's/32/58/' -i tempfile

Now it reads

keycode  58 = +d
    shift   keycode  58 = +D
    altgr   keycode  58 = +eth
(etc...)

To add this remap to the default map, it simply needs to be appended to the remap include file for console-setup

sudo sh -c 'cat tempfile >> /etc/console-setup/remap.inc'

and console-setup needs to be reconfigured (skipping low priority questions with -phigh)

sudo dpkg-reconfigure console-setup -phigh

Now the remap should be completed, and be loaded automatically on boot.

3

I spent one whole day in trying to create a shortcut for Ctrl+Pageup.

I first tried xmodmap but that can't generate modifier events. So it is impossible to create a shortcut that generates for example the Control event.

I then tried xbindkeys with xmacro. That sort of works, but xbindkeys is not able to capture some key combinations on my system, such as Alt + ___.

So I finally used Unity's own Keyboard Shortcuts -> Custom Shortcuts to setup my shortcut.

And instead of xmacro, I have now used xvkbd program to generate the keyboard events, but that is just a personal preference. Both xmacro and xvkbd work almost the same. One additional tip is to add a delay parameter in xmacro or xvkbd to ensure that the events don't get lost.

3

For me AutoKey from Software Center worked the best. It has intuitive GUI, to add new binding click New -> Phrase and

  1. Add name, click OK
  2. At "Phrase Settings" section make sure the paste using is set to keyboard
  3. Add hotkey that you want to use
  4. Add command into text field, eg to emulate left arrow key - it'd be <left> (list of special keys is here).
4
  • This worked perfekt to set up Super+C and Super+V to Ctrl+C and Ctrl+V . Just the perfect solution when using Ubuntu via VirtualBox on a mac
    – user1
    Mar 20, 2019 at 23:06
  • However, this does not disable other commands that listen to these shortcuts. To disable Super+V to "show the notification list" go to Setting -> Devices -> Keyboard and disable it there
    – user1
    Mar 20, 2019 at 23:30
  • 1
    @Ben yup, it would be great if it displayed bindings of other apps, but it's rather icing on the cake. My problem is that it's not possible to remap "Fn" key. I've decided to try out uhk keyboard - that thing programmable independent of os, will see how it goes.
    – Be Kind
    Mar 24, 2019 at 8:05
  • @BeKind Have you succeed with uhk keyboard? Mar 22 at 7:45
3

You could also try https://github.com/sezanzeb/input-remapper

It runs in the background and actively injects mapped keycodes.


While this adds some extra flexibility, if all you need is remap a single button and be done you could try to use xmodmap. Looks like that has already be explained in detail.

Or write an xkb "symbols" file and use setxkbmap, but I wouldn't recommend that. setxkbmap can be used on a per-device basis as well.

Writing xkb or xmodmap configurations caused trouble for me though if both devices report the same keycode, even though the configuration maps them to different characters, when pressing them simultaneously (which is the main reason why I had to write the injection tool for that)

And recently I came across this solution: https://www.reddit.com/r/linux_gaming/comments/k3h9qv/remapping_keys_using_hwdb_files/

2
  • 1
    Couldn't resist to create an extra comment to tell how great key-mapper is! Remapping shortcuts is now a joy! Huge thanks! It definitely should be more popular.
    – DMT
    Jan 10, 2021 at 14:56
  • 1
    Forgot to add that it even works with Wayland!
    – DMT
    Jan 10, 2021 at 15:10
1

If you need to remap a key for a specific program only, I've just added this feature to hax11.

I'd like to change PgUp to Home or PgDown to End.

To do this with hax11, open the program's profile configuration file under ~/.config/hax11/profiles (e.g. ~/.config/hax11/profiles/usr\lib\firefox\firefox), and add:

Enable=1
MapK112=K110
MapK117=K115
1

Non-Persistant remap via .desktop shortcut

In my case I wanted to remap the keypad decimal point to a comma, but only temporarily, so xmodmap satisfies this requirement in my case

  • Find out what is the keycode for the specific key to remap and the keysym I want to map too.
    • :~$ xev | grep keycode
  • Press the keys of interest and monitor the stdout
    state 0x10, keycode 91 (keysym 0xffae, KP_Decimal), same_screen YES,
    XKeysymToKeycode returns keycode: 129
    state 0x10, keycode 59 (keysym 0x2c, comma), same_screen YES,
  • 1st I pressed the key I want to remap and 2nd I pressed the key I want to map to.

    • Keycode of key I want to remap : ..., keycode 91 (...
    • Keysym I want that keycode to map to: ...(keysym 0x2c, comma),...
  • Find out what the current mapping for the keycode to remap is:

    • :~$ xmodmap -pke | grep "keycode\s*91"
keycode  91 = KP_Delete KP_Decimal KP_Delete KP_Decimal

As specified in the manpage of xmodmap: Up to eight keysyms may be attached to a key.. : 1st keysym is used when no modifier key, 2nd with Shift, etc... This does not correspond exactly to what was happening in my case but trial and error allowed me to discover the the 2nd positional argument was the one I was after

  • Map to the new config.

    • :~$ xmodmap -e "keycode 91 = KP_Delete comma KP_Delete KP_Decimal"
  • Map back to original config.

    • :~$ xmodmap -e "keycode 91 = KP_Delete KP_Decimal KP_Delete KP_Decimal"
  • I created a couple .desktop shortcuts in ~\.local\share\applications\ to easily switch to one or the other configuration:

[Desktop Entry]
Name=KeyPad comma
Exec=xmodmap -e "keycode 91 = KP_Delete comma KP_Delete KP_Decimal"
Terminal=false
Type=Application
Icon=/home/paui/.icons/KP_comma.png

Extra info: state field output of xev,

The state field is the "sum" of current active modifiers. These are the ones I deciphered.

    0x01 Shift
    0x02 Caps
    0x04 Control
    0x08 Alt
    0x10 NumLock
    0x80 Alt Gr
0

Using XKB predefined configuration Options

If your lucky, perhaps the specific remap you want to perform is already integrated into a set of predefined options you can add to a your current configuration with setxkbmap.

  1. on a Terminal open the manpage of xkeyboard-config :~$ man xkeyboard-config
  2. Scroll down or search with \ for your specific configuration option. in my case I wanted to remap the keypad Delete key to a comma instead of a period, and I was in luck
 ┌─────────────────────────────────────────────────────────────────┐
 │Option               Description                                 │
 ├─────────────────────────────────────────────────────────────────┤
 │kpdl:dot             Legacy key with dot                         │
 │kpdl:comma           Legacy key with comma                       │
 │kpdl:dotoss          Four-level key with dot                     │
 │kpdl:dotoss_latin9   Four-level key with dot, Latin-9 only       │
 │kpdl:commaoss        Four-level key with comma                   │
 │kpdl:momayyezoss     Four-level key with momayyez                │
 │kpdl:kposs           Four-level key with abstract separators     │
 │kpdl:semi            Semicolon on third level                    │
 │                                                                 │
 └─────────────────────────────────────────────────────────────────┘
  1. check your current keyboard configuration with :~$ setxkbmap -query
rules:      evdev
model:      pc105
layout:     es,gb
variant:    winkeys,
  1. add the option to the current configuration: :~$ setxkbmap -option kpdl:commaoss
:~$ setxkbmap -query
rules:      evdev
model:      pc105
layout:     es,gb
variant:    winkeys,
options:    kpdl:commaoss
  1. To remove all options, use an empty option argument :~$ setxkbmap -option

If you require a mapping that is not predefined there, such as the example you placed, you will need to have to write it yourself as explained in this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .