Etsushi Kato
ek.ka****@gmail*****
2005年 8月 28日 (日) 00:23:01 JST
こんばんは。 On Wed, Aug 24, 2005 at 10:30:12PM +0900, YamaKen <yamak****@bp*****> wrote: > これは以下のような変更によって実現されていますが、ここで加わった > コードはいずれも各IMが責任を負うのではなく、上層で解決されるべき > ものです。できれば修正をお願いします。 この点について少し混乱したので質問させてください (あるいは単なる感想で す)。どの点が、ボトムアップに制御されていて、どの点がトップダウンなの か明確な指針があると助かります。 uim****@fd***** に書こうかと思ったのですが、向こうの ML のシステムがおかしく なっているようなので、anthy-dev に送ります。 まず確認したいのですが、Application (Toolkit) が IM の reset を呼び出 したときに期待されることとして、 o preedit がクリアされる (また言語やそのプリエディットの状態に応じ てプリエディットにあった語が commit される) o 候補ウィンドウがあれば閉じる ということですよね。またプリエディットをコミットするかどうかは、各 IM にまかせるという話でした。 > 次に、(im-update-preedit ac)は各ブリッジが実行すべきです。各IMの > resetハンドラ内ではこれを *呼んではいけません(must not)*。ちゃん > と仕様を書いておかなかったので後出しで申し訳ないんですが、以下の > ような理由によります。 > > uimレベルでのreset操作は、uim_reset_context()を呼び出す事によっ > て行われますが、 > > 例えばQtではtext widgetがresetされると、IMコンテキストをresetす > ると共に、toolkit側でプリエディットをクリアします。IM resetはそ > のtext widgetで各種編集操作(paste, undo等だったと記憶しています) > を行うのに先立って呼ばれる場合があり、IMコンテキストはreset後は > それらの操作を妨げない初期状態になっている事が仮定されています。 > > Qt3ではtoolkit側でwidget毎にIM入力状態のステートマシンを持ってお > り、update-preeditを呼ぶためにはIMStartイベントを受けて入力可能 > 状態に遷移している必要があります。このため、reset時に > update-preeditを呼ぶという事は、たとえ空文字列のプリエディットで > あっても入力可能状態への遷移を引き起こしてしまいます(すいません > がうろ憶えです)。 > > 以上はQtの例ですが、Qtの事情で特別な考慮をしろと言っているわけで > はなく、論理的に考えてreset時のプリエディット消去を各IMが行うの > はresponsibility separationの観点からおかしい(layer violation)と > いう事です。 ここで疑問に思ったのですが、各 IM は、reset 時に内部的な preedit にあ たる文字をクリアするわけで、それを上層に update しろと伝えるのがなぜ、 violation なのかよくわかりませんでした。むしろキー入力中に preedit が 変化する状況と同じわけですから、この伝達は自然に感じます。このように考 えると、中間層が uim_reset_context() を呼んだ後 (前)、さらにそれ自身の preedit clear する機能を呼ぶ必要は感じませんでした。 また上の Qt の例に関しては、入力可能状態でない IM context が preedit の update をしろという callback を受けたときに遷移を引き起してしまうの が単純におかしいように感じます。あるいは、Qt のブリッジが状態を把握し て、callback において toolkit を update させるかさせないか選択すればい いように思うので、ちょっとこの話には関係ないように思います。 現在の uim だとアプリケーション (Toolkit) からのリセットに対して、 o gtk+ の immodule では、ボトムアップ的に uim_reset_context()、つまり IM のリセットにすべてまかせ、あとは callback によって候補ウィンドウ、 preedit が消去される (実際は次の update があるまでされない…) o XIM では、uim_reset_context() + 独自のプリエディットクリア + 独自の 候補ウィンドウ の deactivate (あと、XIM の仕様による、preedit の commit) となっています (Qt は見てません)。 uim_reset_context() は、 o 各 IM にリセットをさせ、libuim 内部のプリエディットを消去、ブリッジのコール バックは呼ばない。 これに対して、IM の方では、anthy, skk を例にとると reset-handler にお いて、 o scheme 内部的な状態のリセット (クリア) + 候補ウィンドウの deactivate、 libuim の内部的なプリエディットは変えない になっています。 経緯はぼくにはわかりませんが、このようにリセット時のプリエディットと候 補ウィンドウに関して一貫性がないような状態ですので、前回の山本さんの変 更がまちがっていたかどうかはわかりません。 ヤマケンさんの仕様では、 IM による内部的な状態の変化 + 中間層による制御 が求められるわけで、現在ある anthy による、候補ウィンドウの deactivate は必要なくなるように感じます。 ここまでは、アプリケーション (toolkit) からのリセットにどう反応 (実装) するかという話です。 次に uim の switch_im に関しては、アプリケーション (toolkit) 側は関係 ありませんが、IM の switch 時には、プリエディットのクリアと候補ウィン ドウの deactivate が必要なわけで、結局上の状況と同じです。実際 uim_switch_im() はuim_reset_context() を中で呼んでいますよね。 で、疑問に思った点なんですが、なんとなく uim 的には bridge 側や IM 側 での特殊な操作なしに、リセットや switch ができるような設計に作りたいよ うに感じてきたので、ブリッジ側での制御という仕様は意外に思いました。 これに関連してもう一つの疑問としては、各 IM が、リセット時のプリエディッ トの update や、候補ウィンドウの deactivate を制御しないとする場合でも、 ブリッジ側でそういった機能を呼ぶのではなく、libuim の uim_reset_context() 内で、それらのコールバックが呼ばれるような仕組みで いいのではと思った点があります。 まとまりませんが、IM リセットに関する、ブリッジ、各 IM、libuim の働き (実装) の整理が必要かなと感じました。 -- Etsushi Kato ek.ka****@gmail*****