如何从gtk+2中的输入法接收字符?

Lea*_*ing 3 c linux gtk gtk2 fcitx

我正在使用 C & gtk+2 和自定义文本输入创建应用程序,将字符绘制到 pango GtkDrawingArea,一切正常,直到用户告诉我他无法在我的应用程序中输入中文字符,他使用 fcitx 输入法.

目前我正在使用 simple key_press_event& key_release_eventGSignals 来实现字符输入,但我认为它不适用于输入法,我找到了一个GtkIMContext api 但不确定如何使用它。

所以,我的问题是,如何从 gtk+2 中的 fcitx/ibus 输入法接收字符?

Lea*_*ing 5

最后我自己找到了方法。

首先,我有一个GtkWindow *.

GtkWidget *window;
Run Code Online (Sandbox Code Playgroud)

为了支持输入法,我要初始化GtkIMContext并设置客户端窗口,gtk_im_context_set_client_window利用GdkWindow *它的第二个参数。

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);
Run Code Online (Sandbox Code Playgroud)

最后一步,将焦点设置为 this im_context

gtk_im_context_focus_in(im_context);
Run Code Online (Sandbox Code Playgroud)

现在输入法可用!在此之后,您可以监听信号GtkIMContext以处理输入。

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);
Run Code Online (Sandbox Code Playgroud)

为了在commit信号的回调中接收英文字符,您必须监听key-press-event信号并使用gtk_im_context_filter_keypress函数。

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);
Run Code Online (Sandbox Code Playgroud)

参考资料:

  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. 如何在 C 中获取 gtk 窗口的 gdk 窗口?