Masanari Yamamoto
h0131****@ice*****
2005年 9月 7日 (水) 15:38:28 JST
山本です。 On Wed, Aug 24, 2005 at 10:30:12PM +0900, YamaKen wrote: > ヤマケンです。こんばんは。 > > At Mon, 22 Aug 2005 21:53:49 +0900, > h0131****@ice***** wrote: > > uim-im-switcherでIMを切り替えるときにプリエディットや候補ウィンドウが > > あると、IMが切り替わってもそれらが消えないことがありました。 > > r1280でcannaとanthyについては消えるように直しました。 > > skkはプリエディットは消えるようにしましたが、再帰学習時の候補ウィンド > > ウを消す方法がわかりませんでした。 > > primeはわからなかったので何もしていません。 > > 0.5.0リリース間近なのに反応が遅れてすいません。 > > これは以下のような変更によって実現されていますが、ここで加わった > コードはいずれも各IMが責任を負うのではなく、上層で解決されるべき > ものです。できれば修正をお願いします。 > > --- trunk/scm/anthy.scm 2005-08-22 11:16:25 UTC (rev 1279) > +++ trunk/scm/anthy.scm 2005-08-22 12:39:24 UTC (rev 1280) > @@ -975,7 +975,10 @@ > (define anthy-reset-handler > (lambda (ac) > (if (anthy-context-on ac) > - (anthy-flush ac)) > + (begin > + (anthy-flush ac) > + (im-clear-preedit ac) > + (im-update-preedit ac))) > ;; code to commit pending string must not be added to here. > ;; -- YamaKen 2004-10-21 > )) > > まず、(im-clear-preedit ac)はuim_reset_context()の中で同等のコー > ドが実行されているので不要です。各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)と > いう事です。 > > なお、uim @ fdoでの以下のresetに関する議論は全て読んだ上での見解で > す。 > > http://lists.freedesktop.org/archives/uim/2005-May/001077.html > reset-handlerでim-update-preeditを呼んではいけないことはわかりました。 複雑な事情があるようですね。 では、IM切り替え時にプリエディットを消すにはどうすればいいでしょうか。 方法は2つあります。1つはuim_siwtch_imでuim_update_preedit_segmentsを呼 ぶ方法(下のパッチ)です。もう1つは各ブリッジが消す方法です。 各ブリッジが消す方法では、 uim-im-switcher-gtk経由でIMを切り替えたときはブリッジがIMの切り替えを 行うのでブリッジからプリエディットを消すことが可能なのですが、 switch-im-keyで切り替えたときは、ブリッジは切り替えが起きたことに気づ かないのでプリエディットを消すことはできません。 uim_siwtch_imでプリエディットを消す方法はどちらの切り替えにも対応でき ます。 Index: uim.c =================================================================== --- uim.c (revision 1434) +++ uim.c (working copy) @@ -230,6 +230,7 @@ UIM_EVAL_FSTRING1(uc, "(release-context %d)", uc->id); uim_release_preedit_segments(uc); + uim_update_preedit_segments(uc); UIM_EVAL_FSTRING2(uc, "(create-context %d #f '%s)", id, engine); if (uc->current_im_name) -- 山本将也