Comment 16 for bug 2561

Revision history for this message
In , Hp-pobox (hp-pobox) wrote :

OK, you guys aren't going to want to go here for 1.0 probably. ;-) But I'll
explain the issues and maybe you want to deal with it eventually.

The original problem I had was a broken keymap, where caps lock was basically on
whenever I was holding control (both Lock and Control modifiers bound to one
key). So Ctrl-a didn't work. This is not really a big deal since I just unbroke
the keymap. But I would expect accelerators to be immune to caps lock, e.g.
imagine a text editor or the Mozilla composer, I'm typing with caps lock on, I
expect "Ctrl-s" to still save - Emacs does this for example, though you may want
to see what more user friendly apps do. However, Emacs treats Shift-Ctrl as
separate from plain Ctrl. It only ignores Lock.

As a bit of a tangent and a larger/harder issue, there are international
keyboards to consider. This is what we haven't fixed yet in GTK unstable version
and are planning to. The issue of ignoring shift/lock is just a special case of
the fact that users expect accelerators to work regardless of keyboard mode. For
example, a Hebrew/English keyboard would normally have a Mode_switch key,
bound to one of Mod1-Mod5, which toggles language. In Hebrew mode, you basically
want the key which generates "S" in English to still mean Save, since it will
drive users nuts if switching modes moves the accelerators around or removes
them. We have user complaints about this. So the way you do that is to query the
X keymap and find out which key generates S in English, roughly. The
keymap-query code is already in GTK unstable, and code to see which modifier is
Mode_switch, but we haven't yet sorted out all the issues; such as what if one
key generates several accelerators in different modes.

The user behavior I think is right is that the same key cap plus the same
non-persistent/non-mode modifiers always generates the same accelerator. So
basically to get the accelerator, you strip off the effects of whichever
modifier Mode_switch controls (one of Mod1-Mod5), strip off the effects of Lock,
then evaluate the result. For English you could just do something like ignore
Lock, or if Lock is set flip the case of the keysym, but ignoring the
Mode_switch modifier is important to, and there you need to query the English
keysym that would have been generated by that keycode absent the mode switch.
Also Num Lock is one of these modal modifiers, which you're already handling
somehow. (Num Lock brings up another pesky issue, which is that the mode
modifiers can apply to only a subregion of the keyboard.)

It isn't really totally clear what the right thing to do is in detail. If you
want I can point you at what we end up doing for GTK when we do it.

Relevant resources would be the Xkb spec from the X distribution, and useful
code from GTK unstable tree is in gdk/x11/gdkkeys-x11.c. I wrote that code and
it's available under MPL if you have any use for it.