72

I cannot make xmodmap run on login in Ubuntu 13.04. I have searched around, including in askubuntu and all answers I found do not work.

I have a file named .Xmodmap in my home folder which contains the desired mappings. If I run it manually it works fine, so there is no error there. In order to make it run on startup, I have tried:

  1. Using various .xinitrc containing one of the following commands:

    • xmodmap .Xmodmap
    • xmodmap ~/.Xmodmap
    • /usr/bin/xmodmap /home/NAME/.Xmodmap
    • if [ -s ~/.Xmodmap ]; then
      xmodmap ~/.Xmodmap
      fi
  2. Using .Xresources instead of .xinitrc with the same variations.

  3. Setting it as a startup application.

None of the above works in Ubuntu 13.04 (64-bit). I also saw a few ideas about globally changing the keyboard mappings, but most of them were not applicable in Ubuntu 13.04 (i.e. the corresponding files did not exist where specified) and I prefer not to touch the global settings anyway.

81

Ubuntu no longer uses xmodmap, but instead uses xkb (as far as I understand, this facilitates per-window keyboard layouts, among other things).

The system-wide map files are in

/usr/share/X11/xkb/symbols/

The maps appears to be loaded hierarchically, with the pc map as the root, and whatever language (e.g. en) as a child of the root.

In my particular case, I physically swapped Page Up with Home and Page Down with End on my keyboard, so I very crudely made changes to the system-wide pc map, as follows:

 key <HOME> {    [  Prior        ]   };
 key <PGUP> {    [  Home         ]   };
 key  <END> {    [  Next         ]   };
 key <PGDN> {    [  End          ]   };

NOTE: To force Xorg to use your new keyboard map, you may have to remove the existing pre-compiled maps (*.xkm) in

/var/lib/xkb/

and then restart Xorg.

There are various resources on xkb, but this one is related to Ubuntu.

  • 9
    As of Ubuntu 14.04, this is sadly the easiest way to swap keys. You CAN make xmodmap run on login by adding it to the Startup Applications, but if you suspend, hibernate etc you must manually start it up or create startup daemon scripts. – holocronweaver Jan 8 '14 at 20:16
  • I can remap keys depending on modifiers: unmodified shift altgr* shift+altgr. But what about left alt and super key? – Farzher Apr 11 '14 at 19:42
  • 7
    I don't think your first sentence is true. Do you have any source for it? I find it hard to believe that "the Ubuntu way" of remapping your keys would be editing the keyboard maps from xkb. Besides being cryptic, this has the problem that your custom maps are deleted when xkb is updated. – Mateus Araújo Jun 15 '14 at 21:36
  • 1
    That said, this is the only reliable method that I've found of remapping keys on Ubuntu. – Mateus Araújo Jun 15 '14 at 21:37
  • 1
    There's got to be a better way. I know the exact keycode I want to map, but keycode 217 isn't even listed in xkb. I don't even see a way to add new keycodes. – Jonathan Dec 27 '14 at 22:18
13

For me, the xkb configuration is too complicated if you want to remap 1 or 2 keys in a way not available in the System Settings. Plus, the solution should remain on the user side, without editing '/usr/share/X11/xkb/symbols/' etc. Force the 'xmodmap ~/.Xmodmap' load using the Startup Applications only works until you suspend, change users or change the keyboard layout. So, as holocronweaver suggests, with code snippets I found, I made a python script to be loaded on session startup, that reloads the '~/.Xmodmap' when needed.

Check the bug report #1243642 (comment #6), and download it here.

  • 1
    Still working as of 15.10 :-) Thanks! – lalomartins Feb 11 '16 at 15:42
  • The link to this legendary script seems to be broken. Could somebody put it up on github? – Epigene Jan 28 '17 at 9:07
  • Great - and only viable- answer! Working in 16.04. To get it to work in Python3 changed: "import gobject" to "from gi.repository import GObject as gobject". – Craig Hicks Feb 21 '18 at 2:51
  • 1
    @Epigene - the link is there now – Craig Hicks Feb 21 '18 at 3:07
  • Praise be! A genius work around. – dmanexe May 7 '18 at 17:33
6

I had this problem in Ubuntu 14.04, and found the solution here. Apparently, Ubuntu is not able to configure the keyboard right away after logging in, but it is a bit later. So if you add a command

sleep 4 && xmodmap ~/.Xmodmap &

to ~/.bash_profile then it should work (it does for me).

EDIT: This seems to work only after logging in, not after starting up. I'll have to investigate this later.

  • 1
    Any luck setting this to run after suspend/hibernate? – Jonathan Dec 27 '14 at 22:34
  • No, unfortunately I still can't even get it to work after booting. So every time I boot, I open a terminal and type xmodmap ~/.Xmodmap :( – dremodaris Dec 28 '14 at 15:19
  • be aware that on ubuntu 16.04 you should use .profile – Vitor Abella Sep 3 '18 at 20:21
5

Convert Caps Lock into Esc for vim use

Here is my variant of a key mapping startup script. It converts Caps Lock into Esc on whatever keyboard for use with vi, vim or gvim.

Unlike the answer of q4w56, this answer does not use any infinite while; do loop. Otherwise, one core of my dual core CPU would hit 42% every 5 seconds, severely reducing my laptop battery charge.

#!/usr/bin/env bash
sleep 4
xmodmap -e "clear Lock"
xmodmap -e "keysym Caps_Lock = Escape"

Save it as a script. Make the file executable with chmod +x. Add the script name and location to Session and Startup → Application Autostart (in Xubuntu).

The keyboard behaviour for this user will remain persistent through reboot and logout, but not suspend. Persistence through suspend can be achieved, but unfortunately only at the system level, not readily at the user level.

Rationale for this keyboard remapping

In today's computing world there is very little use left for the Caps Lock key. In general, one should refrain from using ALL CAPS by virtue of both netiquette and the separation of presentation and content. Moreover, accidentally hitting the Caps Lock key whilst editing text with vim is not always immediately noted, but invariably results in rather annoying vim behaviour further on. Disabling the Caps Lock key all together and repurposing it as an easy to reach Esc key results in a double win for vim use.

  • Replacing the function of the Caps Lock key might be a real life saver for vim users on Apple MacBooks without an Esc key. – Serge Stroobandt Oct 27 '16 at 7:40
  • 3
    It's better to remap the capslock to ctrl. This solves many more problems, and in Vim, then, you can use capslock + [ for Esc Sorry for meddling, but I felt obliged to suggest this. – user907860 Mar 2 '17 at 15:43
  • What exactly is suspend? Is that closing the lid on your laptop? After that your solution doesn't work? How do you use vim after you close the lid on your laptop? – Marko Avlijaš May 29 '18 at 14:47
  • @MarkoAvlijaš How do you use vim after you close the lid on your laptop? By opening the lid of course! – Serge Stroobandt May 30 '18 at 17:50
  • Haha I'd never guess that. I mean caps lock isn't mapped to esc any more after that? – Marko Avlijaš May 30 '18 at 18:16
3

I had the problem too on Ubuntu 16.04 with fcitx, and had the solution on the fcitx wiki, but it need fcitx has 4.2.7 or later

  • touch ~/.Xmodmap
  • write the config
  • reboot and the fcitx will try to load it automatically

There also have some explanation for the reason.

  • 1
    Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference. – Videonauth Jun 8 '16 at 7:36
  • @Videonauth I have modified my answer – Bluethon Jun 8 '16 at 7:44
  • Thank you very much :) I leave my comment here still so the people in review cue can see you changed something. – Videonauth Jun 8 '16 at 7:46
  • @Videonauth this is my first answer and I'm poor of English, so I made some fault. and thx for your advice. : P – Bluethon Jun 8 '16 at 7:49
  • You're welcome. Providing answers is a good way to contribute to the community. – Videonauth Jun 8 '16 at 7:54
3

@Daniel's answer pointed me the right way, but I would like to extend on it.

Works for me on Linux Mint 17.2 and Ubuntu 16.04.

I tried all twists I could think of to keep using xmodmap, but they all fail when the system goes into sleep mode. The same even holds for start up-applicication scripts that use setxkbmap in cases where the *settings-daemon (for me it is xfce4) runs later than the script --- and order cannot really be influenced.

What I finally came up with has the following ingredients:

1) Write a minimal keyboard mapping file for /usr/share/X11/xkb/symbols. Lets call the file mylayout It can be as simple as

xkb_symbols "basic" {
  name[Group1] = "My Layout";
  include "us"
  key <AE03> { [ 3, numbersign, sterling, sterling] };
  include "level3(ralt_switch)"
}
  • basic is just a name, we'll meet it later again.
  • The name[Group1] similarly is just a name it seems, but it will play no role later.
  • include "us" includes the plain us keyboard. Actually us is another file in the same directory. This is the keyboard layout we are adapting. Choose a different one as needed. Note: no semicolon to end this line.
  • The key line is one adaptation of the keyboard, more can follow. The <AE03> can be found in the files under /usr/share/X11/xkb/keycodes. Use the xev program to figure out that the "3"-key has keycode 12 and in the keycodes file Xfree86 it is mapped to <AE03>.
  • Finally another include directive to activate another keyboard option, in this case I want to have the right Alt-key to be the level-3 shift key, i.e. the key which gives access to the sterling sign I defined above. level3 is just a file name in the same folder with ralt_switch one section of it. Have a look around and choose what you need to include.

2) I did not put the mylayout into the system folder. Rather I made only a soft link from the system folder to a folder of my liking to immediately see that this is not stock software.

3) Further I did not fix up evdev.xml, again to prevent update hassles. But this would be necessary to find mylayout in the keyboard configuration editor (for xfce4 it is xfce4-keyboard-settings). Instead I used xfce4-settings-editor and changed keyboard-layout->XkbLayout to mylayout (the file name) and XkbVariant to basic (see above). Afterwards, mylayout/basic is displayed in the keyboard settings editor too. An entry in evdev.xml seems to be only necessary to be able to select the layout.

This way, the keyboard settings now survive sleep mode and reboot.

More background can be found here: http://www.charvolant.org/~doug/xkb/html/node5.html .

Another approach to fixing the sleep mode problem (not tried myself), can be found here: https://www.vinc17.net/unix/xkb.en.html .

UPDATE: worked with Mint 18.3 the same moment I changed the settings in xfce4-settings-editor as described above.

UPDATE: With 18.04, gdm3 as the display manager and XFCE4 as the window manager, it looks as if ~/.Xmodmap is read again and the settings seem to survive a suspend. (I rarely use suspend and I am never sure which mode the laptop is in then really.)

2

REVISION

An update in early 2018 broke persistence -- auto-reload of the keymap after suspend or hibernate. Since methods using /etc/pm/sleep.d scripts stopped working (deprecated?), that left only the newer way, using /lib/systemd/system-sleep and slightly different scripting (which started working on keymaps!).

So this post is updated to the newer method for persistence, and to include normal initial keymap loading, which also started working. The routine for converting an .Xmodmap file to .xkbmap remains unchanged.

Note this is a per-user solution. For a per-device answer, see how to apply a keymap to a single device. This method could be adapted for use here.

First modify the .Xmodmap file as desired. These are easier to edit directly than .xkbmap files. When it is loaded:

xmodmap .Xmodmap

then convert to an .xkb file:

xkbcomp $DISPLAY $HOME/.xkbmap

To auto-load on startup, open Startup Applications, click Add, and on the Command line enter:

xkbcomp /home/user/.xkbmap ":0"

("user" is replaced with actual user name.) For Name, perhaps enter Load Keyboard Map. Add comment if desired and hit Save.

The keymap will now load every time the system boots, but will not survive a suspend or hibernate. For this, create a new file in /lib/systemd/system-sleep, perhaps named 60_xkbmap, which contains:

#!/bin/sh
case $1/$2 in
  pre/*)
    # Place pre-suspend commands here
    exit 0
    ;;
  post/*)
    # Place post-suspend commands here
    export DISPLAY=":0"
    export XAUTHORITY="/home/user/.Xauthority"
    su user -c "xkbcomp /home/user/.xkb/xkb-map $DISPLAY 2>/dev/null"
    ;;
esac

(Ref.) As above, replace "user" with actual user name.

The keymap should now auto-load and remain persistent. Note:

  • Applies to current LTS release, 16.04, and likely later ones as well.
  • Taken from post 14 of the above-linked bug thread.
  • Earlier comments applied to original post.
  • I am trying this method now and now when I start a terminal i get a bunch of messages like so: Warning: No symbols defined for <AB11> (keycode 97) Warning: No symbols defined for <JPCM> (keycode 103) Warning: No symbols defined for <I120> (keycode 120) ...... many more not sure what the consequences of that will be yet. Anyone know? – lost baby Jan 21 '17 at 0:24
  • This method despite the above mentioned warnings works but only temporarily - after a little while the mapping somehow gets forgotten and the super key reverts to its default function. So I'll try it the other way around - I'll remap the basic edit shortcuts on my mac to use the Control key instead of the Command key and see if that works. I just want my cut-copy-paste-undo-redo commands to be the same on Mac and Ubuntu. I get very frustrated when the search menu pops up on Ubuntu every time I try to copy or paste something. – lost baby Jan 28 '17 at 8:38
1

This made me stumble, too, when I upgraded from Ubuntu 12.04 to 13.04.

Luckily this setting is now (or perhaps has always been) easily accessible in the Keyboard preferences and can be changed with a few clicks of the mouse.

  1. Go to System Settings > Keyboard Layout > Options...
  2. In the Keyboard Layout Options, click the arrow to reveal the ▸ Ctrl key position options.
  3. Put the checkmark in at Swap Ctrl and Caps Lock.

There you go: Left Control and Caps Lock have switched positions.

Don't forget to delete ~/.Xmodmap once you've made the change.

  • This was maybe downvoted because it doesn't address xmodmap, but this was actually how I discovered that using Gnome Tweak may have been the reason some of my mappings were acting weird. – dragon788 Oct 30 '17 at 22:14
  • I don't see this in 16.04, is this still possible? – chrismarx Jan 3 '18 at 19:12
  • 1
    @chrismarx No, they removed it. Nowadays (16.04) I set XKBOPTIONS="ctrl:swapcaps" in /etc/default/keyboard. – glts Jan 3 '18 at 20:31
0

I find adding this script to startup satisfying:

while true;do 
    xmodmap -e "keycode 87=Prior"
    xmodmap -e "keycode 88=Next"
    sleep 5
done

I tried using xmodmap ./Xmodmap, but every time it is executed, a noticeable lag will occur.

  • 4
    The use of any infinite while; do loop should be avoided. It caused one core of my dual core CPU to hit 42% every 5 seconds, severely reducing my laptop battery charge! – Serge Stroobandt Apr 17 '16 at 0:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.