[Anthy-dev 56] gtk immodule のメモ
yusuke @ cherubim.icw.co.jp
yusuke @ cherubim.icw.co.jp
田畑です。
いろいろ調べたんで
gtk+のGtkIMContextの説明を書いておきます。
*キーイベント
*コミットした文字列
*プリエディットの変化
*プリエディットの中身
をどういうパスでやりとりするかの設計がミソな感じです。
テキストフィールドの基底クラスGtkTextViewはGtkIMContextの
インスタンスを一つもっていて、入力関係の処理を全部まかせています。
相互のやりとりは
*GtkTextViewはGtkIMContextのメソッドを呼び出す
*GtkIMContextはシグナルを発行して、(普通は)GtkTextViewが
受け取る
というように行われます。
例えばim-uimでのオブジェクトの構成は次のようになっています。
GtkTextView(テキストフィールド)
<>-- GtkIMMultiContext(ディスパッチャとなるInputContext)
<>-- IMUIMContext(UIMのコンテキスト)
<>-- GtkIMContextSimple(キーイベントをそのままコミット
するInputContext)
テキストフィールドにキーイベントがくると、->filter_keypress()
が順によばれてイベントが流れていきます。
(IMUIMContextがGtkIMContextSimpleにイベントを投げるかどうかは、
入力モードに依存します。)
文字列のコミットが必要な場合はシグナルを発生させて、文字列を
伝達していきます。GtkIMMultiContextのcommitシグナルは
GtkTextViewに接続されていて、IMUIMContextのcommitシグナルは
GtkIMMultiContextに接続されています。
文字列のコミットの他に、プリエディットの変更と周辺文字列の取得も
シグナルを用いて行われます。
以下にgtkの gtk/gtkimcontext.h を引用して、コメントをつけときます。
struct _GtkIMContextClass
{
GtkObjectClass parent_class;
/* Signals */
/* GtkIMContextが発生(emit)するシグナルです。 */
/* IMContextがpreeditを変更した時に発生するシグナルです
preedit_startとpreedit_endはそんなに重要ではないと思います。*/
void (*preedit_start) (GtkIMContext *context);
void (*preedit_end) (GtkIMContext *context);
void (*preedit_changed) (GtkIMContext *context);
/* IMContextが文字列をコミットする時に発生させるシグナルです */
void (*commit) (GtkIMContext *context, const gchar *str);
/* 以下二つはよくわかってないです。 */
gboolean (*retrieve_surrounding) (GtkIMContext *context);
gboolean (*delete_surrounding) (GtkIMContext *context,
gint offset,
gint n_chars);
/* Virtual functions */
/* 外部から呼ばれる関数です */
/* 入力対象のwindowをセットします */
void (*set_client_window) (GtkIMContext *context,
GdkWindow *window);
/* TextWidgetはpreedit_changedのシグナルを受け取ると、
InputContextに対してこのメソッドを呼び出して
現在のプリエディットを取得します。 */
void (*get_preedit_string) (GtkIMContext *context,
gchar **str,
/* attrs
文字列の属性、アンダーラインや背景の色、
フォント、サイズなどいろいろな情報 */
PangoAttrList **attrs,
gint *cursor_pos);
/* Textウィジェットはキー入力があると、このメソッドを呼び出します。 */
gboolean (*filter_keypress) (GtkIMContext *context,
GdkEventKey *event);
/* focusが出入りしたときによばれます */
void (*focus_in) (GtkIMContext *context);
void (*focus_out) (GtkIMContext *context);
/* リセットは、テキストウィジェットのフォーカスが移ったなどに
呼ばれます。一般的には*/
void (*reset) (GtkIMContext *context);
/* こっから下は説明できるほど理解していません */
void (*set_cursor_location) (GtkIMContext *context,
GdkRectangle *area);
void (*set_use_preedit) (GtkIMContext *context,
gboolean use_preedit);
void (*set_surrounding) (GtkIMContext *context,
const gchar *text,
gint len,
gint cursor_index);
gboolean (*get_surrounding) (GtkIMContext *context,
gchar **text,
gint *cursor_index);
...
}
--
PUBLISH OR PERISH!
Yusuke TABATA (yusuke @ cherubim.icw.co.jp)
Anthy-dev メーリングリストの案内 |