Why do my xmodmap binds involving AltGr only work on some keys?

Using xmodmap to configure individual key mappings

It is time to write down results of my own research.

I thought that I must have missed something in xmodmap and that it is just not very well documented and people are confused. But it turned out that X.Org design regarding XKB and xmodmap is just stupid.

Epic fail: xmodmap

You can use xmodmap to redefine existing mappings as long as those mappings actually exist in your original keyboard layout. In the case described in the question you cannot extend behavior of any keys to use AltGr. You can only change the AltGr keysyms for keycodes that are already using AltGr.

See also: http://blog.azundris.com/archives/193-X-treme-pain-XKB-vs-XModMap.html

Workaround: Mode_switch

This workaround is described in the answer by @Ned64. You can remap AltGr from ISO_Level3_Shift to Mode_switch.

I successfully used the following command line to remap AltGr.

xmodmap -e 'keycode 108 = Mode_switch'

The disadvantage is that it will break your current keyboard layout but you can recreate all the mappings one by one using xmodmap as @Ned64 already mentioned.

Workaround: Modified keyboard layout

I'm using us(cz_sk_de) as my keyboard layout and I tried to modify it by adding configuration for keys I wanted to extend.

key <AB08>  { [ comma, less, doublelowquotemark, leftdoublequotemark ] };
key <AB09>  { [ period, greater, ellipsis, rightdoublequotemark ] };

(In section xkb_symbols "cz_sk_de" of /usr/share/X11/xkb/symbols/us)

Just reset the keyboard layout to use the modified version.

setxkbmap 'us(cz_sk_de)'

Now you can (1) type Czech and English quotation marks and ellipses using combinations of ,, ., Shift and AltGr keys and/or (2) remap those keys using xmodmap now that they are defined.

The main disadvantage is that setxkbmap doesn't seem to support arbitrary locations for keyboard layouts and therefore you need to write to system configuration instead of your home directory.

Conclusion

This seems to be an example of overengineered and bad design of X.Org where even such a trivial thing as mapping a key code and a combination of modifiers into a symbol turns out to be a problem. The tools don't seem to provide a reasonable way to just change individual key mappings in user configuration without any side effects.


Step one: Make AltGr usable

I found out that AltGr-modified Keys only work on my system if I also remap the AltGr-Key to Mode_switch, like this:

xmodmap -e "keycode 108 = Mode_switch Mode_switch Mode_switch Mode_switch"

If you have a different keyboard you may need to replace the 108 with your code, check by typing

xmodmap -pke | grep Alt_R

then use that number. (The key is normally called Alt_R on systems I know.)

Alternatively, this may also work if Alt_R is not yet assigned to something else:

xmodmap -e "keysym Alt_R = Mode_switch Mode_switch Mode_switch Mode_switch"

Your AltGr modifier will now serve position 3 (with Shift: 4) within your modifier list.

Step two: Assign keys as required

You can assign AltGr-variants for any key of you keyboard you wish. If you have other keys which do not correspond to the desired code now, you need to re-assign these just like your other keys (the ones you tested).

Step three: Convert this into a script

Now just take your xmodmap commands and write all (but only) modifications to your default keyboard into a file - that is faster than loading a complete keymap. Start this script once after each login and whenever the keymap gets reset by some process.

I have experimented with this a lot over the years, under Solaris, IRIX and Linux, and to my knowledge this is the only solution to get AltGr working - and it has worked well for me for more than 20 years.

Tags:

Xmodmap