GNOME Bugzilla – Bug 98447
gtk_im_context_xim_filter_keypress should distinguish XLookupBoth from XLookupChars
Last modified: 2004-12-22 21:47:04 UTC
RH8.0, Gnome2.0, Chines locale 1. Open gedit 2. put focus in the text entry 3. type alt-a expect: no character is printed out result: an 'a' is printed out This bug could be reproduced in almost all gnome2 application which has an editable text entry. Any alt-letter which is not a hotkey is translated as its key symbol without the alt. The reason of this bug is that gtk_im_context_xim_filter_keypress in gtkimcontextxim.c mistakenly treats XLookupChars and XLookupBoth as the same and hide this difference fed back by IM to the upper applications. This bug will block the hotkey for the applications which use gtk+ im but can not use gkt+ hotkey machanism, for example, mozilla. This bug also has some side effect to the gnome2 native applications as above. Not to send alt-letter to gtk+ IM can only be considered as a workaround of this bug. It can hide this bug in some way but not solve this.
Created attachment 12311 [details] [review] proposed patch
In the above patch, when the status is XLookupBoth, we check if the keystroke is really modified by the IM by checking if the length of returned string is longer than 1 and if the returned string is different than the keyval being sent in. If it is not changed by IM, the filter just return false and let the application keeps the original keyevent.
Created attachment 12370 [details] [review] patch according to Owen's advice
(There is a missing check in the latest patch for the status being XLookupBoth) I don't think this approach works at all. A quick check with the default compose-based input method in Xlib (XFree86 Xlib, in this case) indicates that it virtually _always_ returns a status of XLookupBoth. I think the only time when a result of XLookupChars will be when the Xlib Compose tables don't specify a key symbol for the composed combination. Whether a modifier key like Alt is pressed has no effect on this. Without actually trying out your patch, I believe it's result will be that no text input will be possible for most GTK+ apps in most locales when using XIM. Mozilla is probably an exception because it has some handling of converting events to strings outside the input method framework. I don't really see how from the GtkIMContextXIM side we reliably distinguish hot keys of interest to the app from keys of interest to the input method; the application or widget really has to take care of this. [ Robin, Toshi ... please correct me if I am missing something here or am just wrong ]
It does not surprise me that XLookupBoth could be a default return status although I don't think it could be an 'always' return status in some IMEs of certain locale. I also think it's right to return XLookupChars only when there's no key symbol for the combination. That's just my first purpose, to check those still with a key symbol and let those without a key symbol go. My purpose is not to let GtkIMContextXim to distinguish the functionality or meaning of the key. GtkIMContextXim should at least provide applications the right information. There are *TWO* kinds of side effect for this bug. One is to block the hotkey for the application which does not take care of the hotkey before IME, such as mozilla. At the same time, the native GTK applications may also get wrong information about a keystroke just as what I said in the description of the bug. Alt-letters are just coincidently to be wrongly commited while they could be hotkeys in some situation and that's not all. Maybe application can deal with the hotkey but I still don't think to type an alt-a and get an 'a' could just be considered as a feature and I don't think it's the problem only for alt-letters. I should say you are right about the result of my patch. I just realized that if I don't 'commit' the string to the callback, there seems nowhere to deal with the keyevent in Gtk+ any further. We need a more thourough patch. I hope we don't need to change the interface of 'commit'.
What could GTK+ possibly do? Read the mind of the input method? GTK+ has no way of telling that Alt-a _shouldn't_ produce the text 'a' for some input method.
I have explained in my last comment that I never expect Gtk+ to distinguish the meaning of the key or read the mind of IM. On the contrary, what causes this bug is just Gtk+ thinks he knows the mind of IM and mistakenly treats XLookupChar and XLookupBoth as the same. Furthermore, I have said in http://bugzilla.mozilla.org/show_bug.cgi?id=176514#c16 that if Gtk+ does not know the mind of IM why not keep the status information and let the application to deal with it? IM does its work in a proper way and Gtk+ mistranslates it. Although I described the bug with difference between alt-a and a . It is actually the difference bettween XLookupChar and XLookupBoth as in the summary of this bug. Just let me know which is XLookupChar and which is XLookupBoth is OK. I never want Gtk+ could read anybody's mind and tell me which is atl-a and a. Could you be a little patient to read my comments above before you set it as WONTFIX? I think it could be resovled by add one byte in GtkIMEContext. Yeah, you can reject this proposal as long as you can provide me the status somewhere.
With the built-in XLib compose input method: Alt-a => XLookupBoth XK_a/'a' a => XLookupBoth XK_a/'a' Absolutely no difference.
When mozilla used gtk+-1.2, it distinguished XIM's commit events from other key events by chekcking if xevent->keycode == 0 or not. [highly depends on XIM's implementation, but practically it should work in all existing XIM's implementations.] I'd suggest mozilla to do the same, although this is not generically to be done by other gtk+ applications or widgets. Fixing the bug 90082 is required to do so, but mozilla then will be able to use gtk_im_context_filter_keypress() only for keycode 0's xevents. otherwise, mozilla can check alt modifier before gtk_im_context_filter_keypress() is called.
Owen, You still do not catch my point. I began to hate myself to have used that 'alt-a-to-a' example here to demostrate the bug. > Alt-a => XLookupBoth XK_a/'a' > a => XLookupBoth XK_a/'a' > > Absolutely no difference. That is absolutely OK because they both have a keysym with them. But you should not treat them as: Alt-a => XLookupChar 'a' a => XLookupChar 'a' because the BOTH in XLookupBoth means they have two factors - KEYSYM and STRING and Gtk+ does not know which factor is much more important to the application so don't take it for granted to just eliminate the KEYSYM and only give me the STRING. For example, I use the key like 'a' or 'b' or 'c' as a hotkey but I can not integrate it into the Gtk+ hotkey machanism. In normal way, I type the key 'a' and put it into the IM. If I get XLookupChar, it means the IM has generated a string from the keystroke so that I should not use it as the hotkey. If I get XLookupBoth, then I can have a choice whether to use it as hotkey or just give out the string. In current Gtk+ IM implemetion, the status information has lost. I have to compare each string sent back from GTK IM with the previouse character in KeyEvent to guess if it also means a keysym. Isn't it ugly?
Created attachment 12555 [details] [review] A combined path with bug 90082 - see my following comments
Attached a sample patch to follow what I intended above. - keycode=0 keyevents are specifically used by XIM to let XmbLookupString() look up at XIM's commit string buffer. Hence, we can call XmbLookupString() only for these events and gtkcontext's key_press method can return false for any other events. - This is a combined patch for bug 90082 so that a place to call XFilterEvent() and that to call XmbLookupString() should be separated. Firstly, I thought that was necessary, but it may be not so. We may simply do: if (XFilterEvent (...)) return TRUE; if (xevent.keycode != 0) return FALSE; if (xic) XmbLookupString (xic, ...); It's not really my intension to apply this to gtk+ [although I believe it should not break anything in any gtk+ apps], but wondering if only Mozilla can do something similar?
Hmm, I was wrong. if (xevent.keycode != 0) return FALSE; will easily break gtk textviewer and entry. So I wish if only that check could be specifically used by mozilla as it used to do.
Hidetoshi, I have a workaround patch for mozilla at http://bugzilla.mozilla.org/show_bug.cgi?id=176514 . I haven't tried your suggestion yet but I think the purposes might be the same. I applied the idea in my proposed patch here and broke the same thing as yours :). If we can not get the fix from gtk+ soon, we may apply some kind of workaround to mozilla( sure, it depends on the review and super review from mozilla). However, it is NOT a mozilla only bug. All the text entry in gtk+2.0 applications get strange feature as I said in the bug description here. Sooner or latter, people using different locales will find it is inconvient and breaks things here and there. I do hope we can fix it from the bottom but not make patches all around the applications.
But, could this really be an issue for other gtk+ apps? Do you have an example? I don't see anything wrong with accel groups in any other existing gtk+ app even when XIM is enabled for them. In other words, I don't see XIM breaking gtk app's accel groups. [Bug 90082 is the other way where the accel groups breaks XIM...] Unless any live app with the same issue, are we okay to close the bug again?
Please see my first description of this bug. I used the 'gedit' as the example. Type alt-a and get a string 'a' in gedit should not be considered as a feature. Notice that I've never said it will break the accel groups of gtk2 applications. DO PLEASE read my bug description and comments carefully. In fact, this bug does break some shell hotkeys in gnome-terminal. Owen said at http://bugzilla.mozilla.org/show_bug.cgi?id=176514#c15 a VFT widget could sovle this. But I considered it as another upper level workaround for this bug.
There is just nothing that makes sense to do here, no matter how you inerpret XLookupBoth. GTK+ simply doesn't have a concept of a keystroke "sort of eaten by the input method but not really". There may be some relation to GtkIMContextXIM internals if it does something like bug 90082.