brossard@sasun1.epfl.ch ("", Alain Brossard EPFL-SIC/SII) (04/01/91)
While playing with modifiers, I have encountered a few annoying features/bugs/inconsistencies between the keymapping (with xmodmap & Xlib) and the translation manager (Xt). This can also be used as a badly written primer to better understand xmodmap and modifiers. The translation manager in Xt decides that a modifier will generate a "meta" translation symbol for a modifer if it is a modifier for which, at program startup time, there was an associated keysym called Meta_R or Meta_L or both. A mode switch key allows access to the 3rd and 4th character on a keysym. In a related but different way, a key is considered a mode switch key if it is called Mode_switch and is a modifier. BUG: there should be a way to have more than one Mode_switch key. Just naming the keysym as Mode_switch doesn't work, see previous bug report; although there is a way to go around this if we add the keysym to a modifier which is a Mode_switch modifier. This bug has to do with modifier keys being related to key code and not keysym, but I never really understood this since xmodmap uses the keysym and not the key code and leaving us to wonder what happens when there is more than one keycode with the same keysym: the first (?) one gets chosen. > From: der Mouse <mouse@lightning.McRCIM.McGill.EDU> > The xmodmap syntax obscures it, but modifiers are tied to keycodes, not > keysyms. BUG(2): the key is named Mode_switch (note lowercase) rather than Mode_Switch as seems to be the standard. From what I have been told by Justin Bur, the notion that a specific key is a "meta" key is done by the translation manager in xt(?) at startup time. While the notion of Mode_switch is done by Xlib and can be changed during the life of a program. The parsing of meta is done when a program starts up, from that point on, the MODIFIER which is associated with what was considered a META KEY will now generate meta for translation purposes forever. Even if you change the keysym(s) associated with that modifier or move the Meta keys to another modifier! Any running program (like xterm) will always consider that specific modifier as being meta regardless of the actual keysym involved. I consider this a bug, either the MODIFIER is what generates "meta" for translation purposes or a KEYSYM as modifier does. Right now we have a KEYCODE (represented by ONE KEYSYM) as modifier that selects which MODIFIER will be (forever) "meta". Personnaly, I think it would be a lot better if a modifier was defined as "meta". Either all the time, or using another mechanism to associate a certain translation ("meta") to a specific modifier. After all it is the modifier which affects the translation and not the specific key pressed. The situation now is that the keysyms Meta_[RL] select the "meta" modifier, isn't this an arbitrary restriction of having only two "meta" keys? In case the previous wasn't clear: do the following xmodmap - clear mod1 clear mod2 ^D xmodmap - add mod2 = Meta_L ^D start an xterm, Meta_L/mod2 is "meta" for the new xterm, but there is no "meta" for old program anymore, xmodmap - clear lock add mod2 = Caps_Lock ^D Now the caps_lock is also a "meta" key and a modifier2 key for that new xterm, it is only a modifier2 key for all other xterms. xmodmap - remove mod2 = Meta_L add mod1 = Meta_L ^D the caps lock key is still meta in the xterm you have just started but nowhere else! Elsewhere it is just modifier2. The Meta_L key is now modifier1 but not "meta" for that xterm, while it is back to being "meta" for all other xterms. Either xmodmap applies to ALL windows or we invent a new mechanism on a per window basis. But the actual way of dealing with translations is bogus. BUG WARNING So now we understand how "meta" modifiers are selected? What happens if we do the following: xmodmap - clear mod1 clear mod2 ^D xmodmap - add mod1 = Meta_L Caps_Lock add mod2 = Meta_R ^D Start a new xterm, which modifier is "meta"? Both, none? Which key(s) will generate "meta"? Give up? Well so those the translation manager, Caps_Lock Meta_L Meta_R all do NOTHING as regard to "meta". ( Kill that xterm and fix your mapping: ) xmodmap - clear mod1 clear mod2 add mod1 = Meta_L Meta_R add lock = Caps_Lock ^D Mode_switch Now what about the mode switch key, does it work on the same principle? Nope, it has nothing to do with the translation manager, so the binding will vary for all applications whenever you change your mapping. Unless you make the mistake of using a "meta" modifier (or any other magic modifier like "hyper"). In which case, you may get unwanted interaction between the usage as a Mode_switch in Xlib and as a meta modifier in Xt. So here is what I want and a list of the contortions I had to do to deal with them. 1- Caps Lock I want to disable the Caps key, because it interferes with my typing and accelerators every time I hit it by mistake. Yet I would like to keep the feature for the rare times I would need it. So lets define the Linefeed key to do that. But again we get unwanted interaction between Xlib and Xt, Xlib defines the keysym and modifiers and the translation manager does what it pleases (so to speak). Here is the first try: xmodmap - clear lock keysym Caps_Lock = Control_R (I need a keysym which won't generate anything, I first tried Kanji, but the xview toolkit has a bug that it generates a null (^@) for every keysym it doesn't recognize. Control_R is safe) add lock = Linefeed Now, this should work right? Well it has no impact on running Xt programs (xterm): Linefeed is never a Caps Lock, and it generates a linefeed one time out of two. But it does work as a Caps Lock key when checked in an xview window where it also generates a linefeed one time out of two. (When turning the lock on). So there is bug in that Xt never sees it as a Caps Lock (it is called wrong even though it is assigned to the modifier lock), and there is a bug in Xview (Xlib?) that even though it is a modifier, it still generates a symbol related to its keysym. The solution: xmodmap - clear lock keysym Caps_Lock = Control_R keysym Linefeed = Caps_Lock add lock = Caps_Lock It will now work for all programs. 2- Mode_switch using Meta_[RL] I need a mode_switch key, idealy it should be either(both) of the keys named Meta_[RL] on my keyboard. For example, in the following mapping, both Meta_L and Meta_R are considered Mode_switch key and allow access to the 3rd and 4th definition on each key. AND still work as "meta" key for translation purposes. staff%sasun1[29]$ ,x xmodmap - clear mod1 keysym Meta_R = Mode_switch add mod1 = Meta_L Mode_switch Of course, xterm doesn't quite work right yet... The problem this time is a default binding to Meta<KeyPress> and the solution is to add to your .Xressources file the line: XTerm*VT100.Translations: #override \n\ Meta<KeyPress>: insert-seven-bit() It should be added as one of the last line of your translations due to weird (to my mind) scoping rules. Well just for sake of completness, if you want to have a "Compose" key on a sun type-3 keyboard, add the following line via xmodmap: keycode 26 = Multi_key It translates the Alternate key to a Multi_key. This time no modifiers nor translation manager involved. I'm sure I could see the logic of this if I had more time. Sight. I never would have found out the above without the tremendous assistance from Justin Bur and some help from der mouse. Alain