GNOME Bugzilla – Bug 82011
Redo <control><shift>digits code
Last modified: 2011-02-04 16:10:27 UTC
The current code for entering <control><shift>digits is basically fundementally broken ... for one thing, it doesn't allow entering digits where a prefix isn't a valid unicode character. E.g.: <control><shift>de001 Produces [De0]+)+[1] ! What needs to be done is: - Make the <control><shift>digits code not use the tentative_match character, but do the lookup when the sequence ends. - Implement the behavior so: <control><shift> [ anything but a digit ] is ignored by the input method unless already in a sequence <control><shift>digit starts a sequence, and the code eats any number of key presses until a <control><shift> is released, a key is pressed without <control><shift> (hopefully won't happen), the input method loses focus, or <control><shift>space is ignored. During the sequence, <controL><shift>+nondigit is ignored. (Perhaps beeps?) At the end of the sequence, the digits entered are evaluated and if they form a valid unicode character, that is inserted, otherwise, it is ignored (perhaps beeps?)
Right now, <ctl><shift>A9 produces unicode character A9. Depending on how you interpret "digit" in your comment (does it include a-f?), it would mean you'd need to enter <ctl><shift>0A9, the zero necessary to indicate the beginning of a unicode character code. Really, I'd prefer this behavior; it's weird that you can't use ctl+shift+[a-f] as accelerators if the focus is on a text widget. But it is a change...
No, that wasn't what I was suggesting. digit meant <hex digit> above. Requiring a leading decimal digit would make the GTK+ method incompatible with the ISO standard it's implementing, which isn't a big concern. But I'm not sure why people wouldn't want an accelerator for <control><shift>0 equally as well. Also, note that toplevel menu accelerators always win, and the default text widget bindings have nothing on <control><shift>letter.
According to ISO-14755 there are five separate conditions that can be met. Of these, to be compliant, 4 and 5 must be met; 2 is entirely optional; and either 1 or 3 can be used. The "Ctrl+Shift+" input method is condition #1, and hence could be replaced with #3 instead. Condition #3 is the character input map available in GNOME, KDE, and Windows. Hence, GNOME/GTK does not need to implement condition #1. Difficulties arise when GTK binds to the "Ctrl+Shift+[0-9A-F]" key strokes. While top-level menus take precendence, this only works if the developer wants to use top-level menus for all accelerators. It may be that the developer wants to implement her own key binding architecture -- allowing accelerators that do not explicitly appear in top-level menus. In this case, those key strokes are swallowed by the text widget and hence can't be bound. For an example, see the development stream of Eclipse 3.0, and in particular "https://bugs.eclipse.org/bugs/show_bug.cgi?id=42009" This, in and of itself, is not that bad for [A-F], as the shifted characters tend to be the same in different locales. It is possible to make a broad standard that "Ctrl+Shift+[A-F]" are not allowed as accelerators on GTK. Though, there is the minor irritation that "Ctrl+Shift+F" is a very common key binding for "format code". However, the shifted values of [0-9] cover a broad range of characters in different locales. For example, '7' and '/' are co-located on a German keyboard. On a French keyboard, '-' and '6' are co-located. On a Swiss French keyboard, '1' and '+' are co-located. And so on. This isn't a problem, unless the application has defined "Ctrl+Shift+/" as a key binding. This key binding wouldn't work on a German or Swiss German keyboard, as it would trigger a special input mode. So, the key bindings would need to be remapped for the German and Swiss locales. As I was trying to show above, catching all locales for which a key binding may be broken is tricky business. Not only that, but it would become a bit of a maintenance nightmare. I'm wondering if there is a mechanism in GTK where key events can be trapped by an application before they trigger a special input mode. If not, is it possible to add one? Secondly, will GTK reconsider its use of this special input mode, as it doesn't seem to have gained much adoption in other toolkits -- and hence causes some portability problems. Thanks.
Owen, can you suggest a workaround for us? Could we somehow disable this feature?
An application has *complete* control over what sequences it sends to the input method. If you think that it's more important that you get control-shift-digits than the input method gets these characters, don't send them to the input method. (You can even hack this onto standard GTK+ widgets with a ::key-press-event signal handler) I don't want to remvove the ability to do keyboard hex input from GTK+; we aren't implemented the ISO standard just to check the check box but because we thought that keyboard hex input was useful, or at least neat. If someone has good suggestions for alternative key combinations, though changing the particular key combinations might be possible; since Control-shift is just a recommendation in the standard.
Perhaps I'm mistaken, but don't we only have the choice of using all of the input method (including international input methods) or none of it. If you are describing a way we can selectively disable the hex digit input method (while leaving all other input method handling), then I'd be interested in hearing more information. It is only the hex digit input method (in its current incarnation) that is causing problems. On my Windows XP box, "Alt+<numpad_digit>" can be used to enter arbitrary characters (using their decimal representation). I think this is no better or worse then the current method, but has the advantage of providing more seamless cross-platform behaviour (i.e., less surprises for migrating users).
> On my Windows XP box, "Alt+<numpad_digit>" can be used to > enter arbitrary characters (using their decimal representation). But is this possible into all applications, or just those that use the UNICODE ("W") version of the API? (And whose windows are thus marked as "Unicode-enabled" (or whatever the terminology is), so that Windows sends them Unicode versions of keyboard messages.) And is it possible only on XP? GTK's Control+Shift method works on all platforms, even on 9x as far as I know. Plus the fact that using decimal representation of Unicode characters is very uncommon, the canonical way to refer to Unicode values is using hex.
I've never seen "Ctrl+Shift+[0-9A-F]" in native Windows applications. Is there some setting to turn it on? I have seen the "Alt+<numpad_digit>" work on even old versions of windows. Unfortunately, I'm not sure of the underlying mechanism. I am aware of this feature from a user perspective, and not a windows application developer perspective. I also find this hexadecimal digit thing a bit weird. What is the imagined clientele for this feature? Is there a particular use case in mind? If we had an idea of the target audience, we could better tailor the usability aspects of the functionality.
No, Control+Shift+hex digits isn't used by "native" Windows applications (if one by native means applications that use Microsoft's widgets). But try, for instance in WordPad, to type in a few hex digits, then press Alt+x. The hex digits you just typed magically turn into the corresponding Unicode character. Actually, this works if you just move the cursor to the left of some sequence of hex digits that happen to be anywhere in the buffer and type alt+x. Why would Alt+decimal unicode character value be better than Control+Shift+hex (or some other combination+hex)? Surely anybody who knows something about Unicode is used to seeing characters being referred to as hex values, not decimal. And for those who don't know anything about Unicode or code pages, it doesn't really make much difference whether they are told to type Control+Shift+20ac or Alt+keypad08364 for the Euro sign. Both sequences are hoccus-poccus that they will have to keep on a sticky note anyway... Of course, if they need the Euro sign in both non-GTK applications and GTK ones, it's a pain that they have to have two different hoccus- poccus sequences on those sticky notes.
I think we have similar opinions here, but I'm not sure: 1.) This is not something a user is going to understand; so which one is more "natural" is kind of a strange conversation to have. If anyone uses it, they will either be an expert user or they will have the aforementioned sticky note. 2.) Windows supports "Alt+" as the prefix to do raw Unicode stuff, and has been for ages. For GTK to use "Ctrl+Shift+" is to break- away from a de facto standard (yes, even though it is not the recommendation laid out in the real standard). My original opposition to the "Ctrl+Shift+" prefix is that it interferes far too readily with key bindings. The input mode would need to be modified to get around this fact. Compare with the "Alt+<numpad_digit>" approach which works all the time -- no exceptions or special conditions.
> I think we have similar opinions here, but I'm not sure Yes, we are "violently agreeing" ;-) However: > Windows supports "Alt+" as the prefix to do raw > Unicode stuff, and has been for ages. Here I think I must disagree. What has been supported for ages is alt+keypad digits *without a leading zero*, which refers to the current codepage, not Unicode.
Although I didn't read the ISO standard I suggest to trigger on Ctrl+Shift+[0-9A-Z] in GTK widgets ONLY when at least 2 of them are entered in sequence (Ctrl+Shift pressed, TWO ore more hex digits pressed, Ctrl+Shift released), otherwise deliver the key sequence unchanged to the application. - There seem not too many uses of entering unicodes 0x00 - 0x0F this way - users thinking hex often think in bytes/octets, not nibbles. E.g. the widnows line delimiter is most often referred to as "0D 0A" (or "13 10"), I have never seen that written as "D A" - almost any unicode chart I have seen lists 2 or 4 nibble sequences This would open up the Ctrl+Shift+[0-9A-F] sequence for usage by applications. Best regards, Georg
Not possible - if someone hits <control><shift>a you have to decide *then* what to do with the key ... you can't wait until the user hits another key *then* go back and trigger an accelerator.
So, again, I would ask that their either be some facility for selectively disabling this functionality (preferred) or that this functionality be switched to use some other modifier key(s).
Created attachment 51678 [details] [review] a patch Here is a patch which changes the hex input to only be initiated by C-S-u, followed by C-S-<hexdigit>. Releasing Control or Shift, or pressing C-S-space commit the character. The preedit display includes the initial 'u'. It seems to work fine in general, the only problem I see is when I type eg C-S-(u,a,a,a) (or any other sequence which doesn't lead to the insertion of a character), typing backspace immediately after that will not delete the preceding character. Repeating the backspace fixes it. I think this is a problem of the textview getting confused about the cursor position. But it also seems to happen when I right-arrow over the end of the buffer, so it may well be independent of the input method. It should theoretically be possible to change the trigger sequence from C-S-u to something else, perhaps with a setting. If we decide to do that, it should also be easy to turn it off completely.
Owen, it would be great if you could look at that patch. I'm not a natural born input method hacker...
two extensions that might be nice are 1) handling backspace while accumulating digits 2) allow to release C-S immediately after pressing C-S-u and accumulate digits without holding C-S until space, since holding C-S while entering the hex sequence is not very convenient
2005-09-02 Matthias Clasen <mclasen@redhat.com> * gtk/gtkimcontextsimple.c: Rework the Unicode hex input code. Now we only steal a single key combination, Ctrl-Shift-U, instead of sixteen. A hex Unicode sequence must be started with Ctrl-Shift-U, followed by a sequence of hex digits entered with Ctrl-Shift still held. Releasing one of the modifiers or pressing space while the modifiers are still held commits the character. It is possible to erase digits using backspace. As an extension to the above, we also allow to start the sequence with Ctrl-Shift-U, then release the modifiers before typing any digits, and enter the digits without modifiers. (#82011, Owen Taylor)
Very nice. I suggest Ctrl-Shift-U commits the character and start a new one too. this way you press C+S and press u1234u5678u00a9u0e2c..., and of course no character should be emmited if no digit has bee types, such that multiple spaces/U-characters don't do anythin. For extra credit accept plus chars too, such that C+S "U+200E U+00AB" work :-).