How to receive characters from input method in gtk+2?

1.1k Views Asked by At

I'm creating a application using C & gtk+2 with custom text input, pango to draw the characters to GtkDrawingArea, everything works fine until a user tells me that he can't input Chinese characters in my application, he use a fcitx input method.

Currently I'm using simple key_press_event & key_release_event GSignals to implement character input, but I don't think it will work for input methods, I found a GtkIMContext api but not sure how to use it.

So, my question is, how to receive characters from fcitx/ibus input methods in gtk+2?

1

There are 1 best solutions below

0
On BEST ANSWER

Finally I found the way myself.

First of all, I have a GtkWindow *.

GtkWidget *window;

To support input methods, I have to initialize a GtkIMContext and set the client window, gtk_im_context_set_client_window use GdkWindow * as its second parameter.

GtkIMContext *im_context = gtk_im_multicontext_new();
GdkWindow *gdk_window = gtk_widget_get_window(GTK_WIDGET(window));
gtk_im_context_set_client_window(im_context, gdk_window);

The last step, set focus to this im_context.

gtk_im_context_focus_in(im_context);

Now the input methods are available! After this, you can listen for signals of GtkIMContext to handle inputs.

g_signal_connect(im_context, "commit",
      G_CALLBACK(commit_callback), NULL);
g_signal_connect(im_context, "preedit-changed",
      G_CALLBACK(preedit_changed_callback), NULL);
g_signal_connect(im_context, "retrieve-surrounding",
      G_CALLBACK(retrieve_surrounding_callback), NULL);
g_signal_connect(im_context, "delete-surrounding",
      G_CALLBACK(delete_surrounding_callback), NULL);

In order to receive english characters in commit signal's callback, you must listen for key-press-event signal and use gtk_im_context_filter_keypress function.

static gboolean key_callback(GtkWidget *widget,
                             GdkEventKey *event,
                             GtkIMContext *im_context) {
  return gtk_im_context_filter_keypress(im_context, event);
}

g_signal_connect(window, "key-press-event",
      G_CALLBACK(key_callback), im_context);

Refenerces:

  1. https://github.com/GNOME/gtk/blob/gtk-2-24/gtk/gtkentry.h
  2. https://github.com/GNOME/gtk/blob/gtk-2-24/gtk/gtkentry.c
  3. https://developer.gnome.org/gtk2/2.24/GtkIMContext.html
  4. How do I get the gdk window for a gtk window in C?