12

I can't seem to find a way to use Caps Lock as the compose key properly. Some methods are not portable since they require that you detect the key number using something like xev on every host. Other methods result in a ~/.Xmodmap which cannot be passed to xmodmap more than once without bad keysym and similar errors. This makes it difficult to test changes to the file. Is there some way to do this in ~/.Xmodmap?

l0b0
  • 51,350
  • Have you seen this? http://unix.stackexchange.com/questions/90089/remapping-both-caps-lock-and-shiftcaps-lock-in-xkb – UVV Jan 07 '14 at 18:52
  • How portable do you need to be? With xmodmap, you can be portable to all PCs and idempotent, or portable to hardware that's pretty exotic nowadays but non-idempotent. – Gilles 'SO- stop being evil' Jan 07 '14 at 23:19
  • All solutions to this that I've encountered were not idempotent on Arch Linux. That is, running xmodmap ~/.Xmodmap repeatedly results in errors. I'm sure it's possible to be idempotent with xmodmap, it just doesn't seem at all obvious how to achieve this. – l0b0 Jan 08 '14 at 10:11
  • @l0b0 Try running setxkbmap to clear the keyboard map between runs to make it idempotent. – lily Jan 08 '16 at 20:16
  • @IstvanChung How do you "clear" it? Just running setxkbmap doesn't do it. – l0b0 Jan 08 '16 at 22:30
  • On my system at least, running setxkbmap restores the modifier map to the state before Xmodmap was run. – lily Jan 08 '16 at 22:32

2 Answers2

12

You are having problems with idempotency because you are using keysym instead of keycode. Think of keycode as being an assignment of a key to a function, while keysym is just a link from a function name to an actual function.

When you use keysym as follows:

keysym Caps_Lock = Multi_key

you essentially delete the name Caps_Lock. Therefore, the next time you run xmodmap and you reference Caps_Lock in this same line, it gets confused.

The correct way to do it is to reassign the keycode directly as follows:

keycode 66 = Multi_key

You can get the keycode from the xev command for example.

  • How can it ever be portable if I have to get the key code from xev? Also, my keysym command works idempotently on one machine I'm using. – l0b0 Jan 15 '14 at 19:05
  • It is portable as this 66 as long as you use the evdevdriver in Xorg. In this case, the value is defined at /usr/share/X11/xkb/keycodes. How portable do you need your solution to be? What OSes, what keyboards, etc? If you just use regular USB keyboards on Linux it seems that this solution is portable. – Nicolas Dudebout Jan 15 '14 at 21:03
  • So far it has to be compatible with at least a laptop and three desktops, all with different keyboards and with Arch Linux, Fedora and Red Hat. – l0b0 Jan 15 '14 at 21:15
  • So this works. All Linux and standard keyboards. – Nicolas Dudebout Jan 15 '14 at 21:17
  • Alright, I'll try it. It would be very helpful if the answer enumerated the compatible *nixes, if possible. – l0b0 Jan 15 '14 at 21:26
1

This .Xmodmap works idempotently:

! Use Caps Lock button for compose key
keysym Caps_Lock = Multi_key Caps_Lock

! Remove shift lock functionality
clear Lock

After logging in Caps Lock works as the compose key. After running xmodmap ~/.Xmodmap manually it still works, and there are no error messages.

Unfortunately it's not portable:

$ xmodmap ~/.Xmodmap
xmodmap:  /home/username/.Xmodmap:2:  bad keysym target keysym 'Caps_Lock', no corresponding keycodes
xmodmap:  1 error encountered, aborting.
l0b0
  • 51,350
  • I'm using keycode 66 Multi_Key and it seems to work for me. I read your other comments and am curious: Is the keycode for CapsLock really different on one of your machines? – exhuma Oct 08 '14 at 07:44
  • There's a typo: it's Multi_key not Multi_Key. Lower-case k. – Jack Deeth Sep 05 '17 at 12:00
  • It seems that it is also not durable. I just tried this on a fresh Fedora install, and while harmless, it was also ineffective. – 4dummies Jan 24 '22 at 22:20