この日記はMozillaのプロダクトへの貢献者としての私の成果を中心に、気になったバグやWeb界隈の話題について書いていますが、 断り書きがある場合を除き、いかなる団体のオフィシャルな見解ではありません。あくまでも個人的なものです。 Mozilla Foundation、Mozilla Corporation、及び関連企業の公式情報ではないことに注意してください。

現在、XHTML 1.0 (もどき)から、HTML5なコンテンツに修正中です。古い日記は修正が完了していませんので表示が崩れます。 順次、修正していく予定ですのでしばらくお待ちください。

もずはっく日記(2013年2月)

2013年2月7日

Bug-org 838001 Input Method can't be opened to type to input fields in a panel on Firefox 19+
初回投稿日時: 2013年02月07日19時33分28秒
最終更新日時: 2013年02月07日23時18分57秒
カテゴリ: Firefox Mozilla Core Mozilla19 Mozilla20 Mozilla21 バグ修正
SNS: (list)

Firefox 19以降では、Add-on SDKで生成した"panel"上にある<input type="text">や、<textarea>等ではIMEが利用できない、というバグです。重大なIMEのregression報告をえむけいさんが発見し、私をCCしてくれたのが不幸中の幸いでした。本当に感謝、感謝です。

このregressionの発生経緯が少しややこしいのですが、まず、Bug-org 705057の修正で、IMEに強制確定をリクエストする際に仲介するnsIWidgetnsPresContextから取得するメソッドを、nsEditor::GetWidget()や、nsDOMWindowUtils::GetWidget()パクり参照し、nsPresContext::GetNearestWidget()というメソッドを作成しました。その内容は名前の通り、nsPresContextの管理しているnsIPresShellのルートフレームを持つ、もっとも近い親のnsIWidgetを返すようにしていました。

次に、これは便利なメソッドで読みやすい、ということで、Bug-org 802896の修正で、nsIMEStateManager::GetWidget()を削除し、IMEの管理コードは全て、nsPresContext::GetNearestWidget()を利用して、IMEと仲介してくれるnsIWidgetを取得するようにしました。

さらに、nsIMEStateManager::GetWidget()と同じ方法でnsIWidgetを取得していたコードがnsTextStateManagerの生成箇所にもあったので、Bug-org 805306の修正時に、nsPresContext::GetNearestWidget()を利用するようにしていました。

しかし、Bug-org 802896の修正時に疑問だったのですが、nsIMEStateManager::GetWidget()nsPresContextのトップレベルのnsIWidgetを返していました。違いは気になっていましたが、異なる値を返すパターンをwidget removalの成果もあったおかげで発見できませんでしたので、問題はないと判断しましたが、このケースが発見された訳です。

Add-on SDKの作る"panel"は、フォーカスを失うと自動的に閉じてしまうために、デバッグしにくく、その正確な正体を掴めていませんが、デバッガで様子を見ている限りは、そのアドオン用に独立したnsPresContextを作り、さらに、子ネイティブウイジットを"panel"用に生成して、その上にコンテンツを配置しているようです。ですが、実際にフォーカスをもつネイティブウイジットはその親にあたる、トップレベルウイジットの用な症状です。

そこで、nsIMEStateManager::GetWidget()と同じ値を返す、nsPresContext::GetRootWidget()を作成し、IME関連のコードは全てこれを利用するようにしたところ、バグを修正できました。

これらの結果からすると、パクった参考にしたnsEditor::GetWidget()と、nsDOMWindowUtils::GetWidget()はIME関連で利用されるのは間違ってると言えます。前者は強制確定を行うために使われていましたが、各プラットフォームで、子ウイジットで呼び出された強制確定の処理は、同一のコンテキストを持つ、他のウイジット上でも機能しますし、後者は自動テストでの偽Compositionイベント生成用ですので、間違ったnsIWidgetからイベントが生成されても行き着く先は同じなので問題になりません。

今回のバグはFirefox 19以降で発生していますが、こちらは、かなり深刻ですので、Firefox 19以降、全てのブランチで修正が行われています(なんと、マージのタイミングの問題から、mozilla-centralよりも先にbetaで修正されてしまいました)。

関連するかもしれないエントリ

bug-org 838001を含むエントリ