Input method support in Gtk



Hi Gtk world,
I'm an input method developer under Linux. As promised in another
mail, I'd like to propose some problem within Gtk application. As far
as I develop input method under linux and especially for Gtk, I think
I find some problem inside Gtk regularly make Gtk application cannot
work with input method correctly.

Let's suppose that input method represents "keyboard-based input
method" in below, since on-screen keyboard can be also think as
another kinds of input method, but that's a different story. For those
who don't know, input method is heavily used by CJK user and also some
other non-English user in the world. You could think input method as
another kinds of keyboard layout, though quite more complicated.

Input method is supposed to work like this.

Raw keyboard event -> application -> input method
-> if input method accept it, then application should ignore such key event.
-> if input method ignore it, then application will process key even as normal.

1.
So there is a fundamental problem inside Gtk, which is Gtk cannot
guarantee the key event always send to input method first. This is
what must be ensure to make input method work correctly.

And that's why nearly all existing input method use gtk_key_snooper to
grab the key event, which is a dirty hack for me, but without it,
input method can hardily work correctly. For example, mozc is an
japanese input method, which use "Tab" to select candidate words, but
without key snooper, "Tab" will be processed by gedit as indent first,
and thus it will not work.

And key snooper will not always work. [2]

2.
There is also some other trouble in glib, that GCallback is not type safe,

Here is an example of a pidgin bug:

g_signal_connect(G_OBJECT(gtkconv->entry), "key-release-event",
                 G_CALLBACK(gtk_conv_key_press_cb), NULL);

static void gtk_conv_key_press_cb(GtkWidget *tv, GdkEventKey *event,
gpointer data)
{
       gboolean togglemenus = purple_prefs_get_bool(PREF_TOGGLE_MENUS);
       gboolean enabled = purple_prefs_get_bool(PREF_ENABLED);

       if(enabled && togglemenus){
               if(event->state & GDK_CONTROL_MASK){
                       if(event->keyval == GDK_F11){
                               ToggleConvMenu();
                       }
               }
       }
}

But actually this callback requires a gboolean return value. Which
also cause input method cannot work correctly.

3.
This is a feature request, that widget should have kinds of "Hint" for
input. This is being used in android and qt.
That a input field can indicates what the content suppose to be, such
as password, email address, or digit. This is a useful info for input
method to work better.
Currently, input method could only use things like

            GtkWidget *widget;
            gdk_window_get_user_data (fcitxcontext->client_window,
                                      (gpointer *)&widget);
            if (GTK_IS_ENTRY (widget) &&
                    !gtk_entry_get_visibility (GTK_ENTRY (widget))) {
                 .....
            }

to guess the password type, but what about if it's not GtkEntry? This
is what happened in gnome-shell, since it use a totally different
widget system.

So how to solve this?

My proposal is:
1. make input method to use key_snooper as a standard way for input
method, in order to make sure key even is processed.
2. give a application global properly for which widget is being
focused. and widget should have a hint it need input method or not, if
not, key event need not send to input method in this case.
3 .add some automatic code check for case 2.
4. add api to query input method hint, and emit signal when hint changes.

[1] http://en.wikipedia.org/wiki/Input_method
[2] https://bugzilla.gnome.org/show_bug.cgi?id=669080


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]