Bug-org 511534 Poor interaction with the software keyboard
初回投稿日時: 2009年08月27日14時49分46秒
最終更新日時: 2009年08月27日18時14分26秒
カテゴリ: Mozilla Core バグ修正
SNS:
Tweet (list)
Dougから昨日、直接GTK2 widget部分のログが送られてきて、なんか変な動作になるんだが心当たりあるのかと聞かれました。
1073790592[40338110]: IM_commit_cb 1073790592[40338110]: OnContainerFocusInEvent [4038a600] 1073790592[40338110]: SetFocus [40fb2e00] 1073790592[40338110]: IMESetFocus 40fb2e00 (4357e540) 1073790592[40338110]: IMELoseFocus 40fb2e00 (4357e540) 1073790592[40338110]: widget now has focus in SetFocus() [40fb2e00] 1073790592[40338110]: IMESetFocus 40fb2e00 (4357e500) 1073790592[40338110]: [40fb2e00] Opening Hildon Keyboard (4357e500) 1073790592[40338110]: Events sent from focus in event [4038a600] 1073790592[40338110]: OnContainerFocusOutEvent [4038a600] 1073790592[40338110]: IMELoseFocus 40fb2e00 (4357e500) 1073790592[40338110]: IMELoseFocus 40fb2e00 (4357e500) 1073790592[40338110]: IMESetFocus 40fb2e00 (4357e540) 1073790592[40338110]: IMELoseFocus 40fb2e00 (4357e540) 1073790592[40338110]: [40fb2e00] Closing Hildon Keyboard (4357e540) 1073790592[40338110]: Done with container focus out [4038a600] 1073790592[40338110]: OnContainerFocusInEvent [4038a600] 1073790592[40338110]: SetFocus [40fb2e00] 1073790592[40338110]: IMESetFocus 40fb2e00 (4357e540) 1073790592[40338110]: IMELoseFocus 40fb2e00 (4357e540) 1073790592[40338110]: widget now has focus in SetFocus() [40fb2e00] 1073790592[40338110]: IMESetFocus 40fb2e00 (4357e500) 1073790592[40338110]: [40fb2e00] Opening Hildon Keyboard (4357e500) 1073790592[40338110]: Events sent from focus in event [4038a600] 1073790592[40338110]: OnContainerFocusOutEvent [4038a600] 1073790592[40338110]: IMELoseFocus 40fb2e00 (4357e500) 1073790592[40338110]: IMELoseFocus 40fb2e00 (4357e500) 1073790592[40338110]: IMESetFocus 40fb2e00 (4357e540) 1073790592[40338110]: IMELoseFocus 40fb2e00 (4357e540) 1073790592[40338110]: [40fb2e00] Closing Hildon Keyboard (4357e540) 1073790592[40338110]: Done with container focus out [4038a600] 1073790592[40338110]: IM_commit_cb
時系列は上が古く、下が新しいものです。これを見ると、フォーカスがセットされたり、奪われたりしていることが分かりますが、Doug曰く、Closing Hildon Keyboard
は呼ばれるべきではない、とのこと(Hildon KeyboardとあるログはDougがローカルで追加したもので、実際のコードには入っていません)。
コードとログとを照らし合わせてみると、元々の私の設計とは明らかに異なる部分があることが分かりました。それはOpening/Closing Hildon Keyboard
直前のIMESetFocus/IMELoseFocus
の呼び出し履歴です。
これらはコードを見る限り、明らかにSetIMEEnabled
からの呼び出しです(他からの呼び出しならこの直前の行に呼び出しもとのログが残るようになっています)。ですが、Dougのテストはあくまで、ひとつのフィールド上にフォーカスを当ててのものですので、ネイティブなフォーカスイベントが発生していたとしても、Gecko上でのフォーカスの移動は無い(DOMで言うと、activeElement
に変化はない)はずです。ですので、SetIMEEnabled
が呼び出されること自体がバグです。また、例え呼び出されたとしても、安全策が取り入れられていて、activeElement
に対応したIMEの状態を送られているのであればSetIMEEnabled
は直ちにその呼び出しを無視して、何も行わないのでバグは抑制されているはずです。
つまり、SetIMEEnabled
が間違えたタイミングで、間違えた状態と共に呼び出されていることになります。
ここでさらに、Closing Hildon Keyboard
直前の、IMELoseFocus
に注目してみると、その間違えた状態というのは、IsIMEEditableState()
がtrue
を返す時だと分かります。そう、つまり間違えて送られてきている状態は、nsIWidget::IME_STATUS_DISABLED
であると分かります。
もちろん、実際にはフォーカスが移動していないのですが、nsIWidget::IME_STATUS_DISABLED
が設定される、ということはフォーカスを持った要素が無くなった、という意味ですので、ログから察するに、ウインドウがdeactiveになるときに誤って、これを呼んでいる可能性が高いと言えます。
で、ここ数ヶ月、こんな変化が何で起きたか推測してみると、focus refactoringしか思い当たりません。ここでは、SetIMEEnabled
を呼び出す、nsIMEStateManager::OnChangeFocus()
の呼び出しコードをnsEventStateManager
からnsFocusManager
に移動し、集中管理するようにしたからです。するとやはり、ウインドウがdeactiveになる時にもnsIMEStateManager::OnChangeFocus()
が呼び出されていることが分かったので、リンク先のバグでのレビュー結果となっています。
ちなみにこのバグ、Fennecで発見されましたが、Window ManagerによってはLinuxでも発生しているはずです。片貝さんが以前、これの実装をするときのレビューで教えてくれたのですが、一部のWindow ManagerはIMEの候補ウインドウ等にフォーカスを移してしまって、Fx自体がdeactiveになってしまう可能性があるそうです。もしそうなった場合、trunkでは強制的に確定されるようになってしまっていました。そう、かなり重大なバグであったにも関わらず、ここまでバグ報告が無かったのは、そういったマイナーな環境をテストできるほど、テスタの確保(確認する目を増やす、というもともとの理念)が、IMEに関してはまだまだできていないと言えるでしょう。