Bug-org 569023 IME composition is committed unexpectedly when the focused window is hanging up on Vista and later
初回投稿日時: 2010年08月09日14時38分22秒
最終更新日時: 2010年08月10日11時40分11秒
カテゴリ: Mozilla Core バグ修正
SNS:
Tweet (list)
Windows Vista以降ではウインドウになんらかの入力を行おうとした時に、そのプロセスがビジー状態だと、ウインドウ全体を白っぽく描画するようになっています。この時に、内部ではWM_IME_SETCONTEXT
が送信され、一度IMEのコンテキストをdeactiveにしようとします(プロセスがビジー状態なのだから、この意義はよく分かりませんが)。Geckoはこのメッセージをフォーカスの移動だという前提で無条件に強制確定を行ってたため、なんらかの処理でFxがビジー状態に陥ると入力中の文字が確定され、辞書にも悪影響を及ぼしているかもしれない、という状況でした。
この修正では、まず、Geckoには直接関係のない、トップレベルウインドウへのWM_IME_SETCONTEXT
は無視するようにしました。Deactiveなウインドウ内の子ウインドウがフォーカスを取得すると、最初にウインドウをアクティブにするためにトップレベルウインドウにフォーカスを与える処理が行われ、WM_IME_CONTEXT
が送信されてしまいます。当然、このメッセージを処理する必要性はありません。
次に、wParam
が非ゼロで、変換中のウインドウが他にあれば、これを強制確定するようにしました。GeckoはすべてのウインドウでひとつのIMEコンテキストを共有しているため、未確定文字列が他のウインドウで処理されるのを防ぐ必要があるためです(様々な理由から未確定文字列の持ち越しは行っていません)。つまり、wParam
がゼロの場合には強制確定を行わなくなりました。
これにより、IMEの変換途中にFxのすべてのウインドウがdeactiveになっても強制的に確定されることはなくなりました。例えば、未確定文字列を適当に入力し、別のアプリケーションに切り替えて、再度、編集中のFxのウインドウをアクティブにすると、変換作業を継続できるようになりました(ただし、タイトルバー等の非クライアント領域以外をクリックしてアクティブにすると強制確定されてしまうので注意してください)。
さて、話はここで終わるはずだったのですが、パッチのテスト中によりややこしい話を見つけてしまいました。windowlessプラグインはフォーカスを失う際に強制確定を行ってくれません。これはWindowsアプリとしては正しいというか、より好ましい動作ではあるのですが、Geckoのローカルルールとの相性がすこぶる悪いのです。
対策として、windowlessプラグインのメッセージの中継処理のうち、IMEやキー入力に関連するものを丸ごとnsWindow
からnsIMM32Handler
に移動し、windowlessプラグイン上でIMEの編集処理が完結しないままフォーカスの移動が発生した場合には強制確定を行うようにしました。
ところが、これだけでは新たにフォーカスを取得したウインドウ上に文字が入力されるというバグが発生してしまいました。Flash PlayerではWM_IME_COMPOSITION
やWM_IME_CHAR
をきちんと処理していないようで、強制確定により、WM_CHAR
が生成されてしまい、これが新しいフォーカスウインドウで受信されていたのです。
これに対抗するために、WM_IME_CHAR
をプラグインに渡した後、処理されていない場合にはメッセージの内容を保存し、その後にWM_CHAR
を受信した時に同内容のものなら無視するようにしています。ただし、安全策として、もし内容の異なるWM_CHAR
を受信するとそれ以降のWM_CHAR
は無視しなくなるので、入力ができなくなる、といった問題は発生しないはずです。
今回の修正で、windowlessプラグインのIMEの状態もある程度はnsIMM32Handler
で監視するようになりました。このため、変換中かどうかの状態管理の変数が二重化されています。変換中かどうかの判定のためにstaticメソッドを用意しているので、変数を直接見ることとの意味の違いを知っておかないとバグを作り込んでしまうことになるので注意が必要です。