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.