[Anthy-dev 56] gtk immodule のメモ

アーカイブの一覧に戻る

yusuk****@cheru***** yusuk****@cheru*****
2002年 12月 25日 (水) 02:36:32 JST


田畑です。

いろいろ調べたんで
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 (yusuk****@cheru*****)



Anthy-dev メーリングリストの案内
アーカイブの一覧に戻る