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:
Tweet (list)
Firefox 19以降では、Add-on SDKで生成した"panel"上にある<input type="text">
や、<textarea>
等ではIMEが利用できない、というバグです。重大なIMEのregression報告をえむけいさんが発見し、私をCCしてくれたのが不幸中の幸いでした。本当に感謝、感謝です。
このregressionの発生経緯が少しややこしいのですが、まず、Bug-org 705057の修正で、IMEに強制確定をリクエストする際に仲介するnsIWidget
をnsPresContext
から取得するメソッドを、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で修正されてしまいました)。