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

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

もずはっく日記(2009年4月)

2009年4月11日

Bug 6574 マルチディスプレイ環境で、プライマリディスプレイ以外のウインドウからメニュー等を開いても、プライマリモニタに表示される
初回投稿日時: 2009年04月11日10時34分01秒
最終更新日時: 2009年04月11日10時38分22秒
カテゴリ: Mozilla Core バグ修正
SNS: (list)

忙しい時に限って、こういう使い物にならないバグが出てくるもんですね。私の環境は、一番よく作業で使うディスプレイがプライマリモニタではないので、ここ最近のビルドは使いにくくて仕方がありませんでした。

で、コメントに書いてあるとおり、セキュリティバグからのregressionなので詳しくは書けないのですが、このセキュリティバグは、自動テストを作ってみたところ、クラッシュするぞ、という話に基づいています。ところが、そのテストが通常利用では、もっと言うなら人間では再現不能なバグなので、おそらくこのテストされているUIがこんな状況を再現していないと思われるのと、Geckoもそんなタイミングで二つのreflowが発生することを想定していないので結果、クラッシュしてるんではないか、と推測されるものでした。

そのクラッシュの原因のひとつは、nsIDeviceContextがネイティブウインドウの生のポインタを持っているのに、nsIWidgetより微妙に長生きすることが直接的な原因のようでした。そこで、セキュリティバグではnsIWidgetが破棄される時に常にnsIDeviceContextを再初期化してポインタをNULLにしていたのですが、nsIDeviceContextを複数のnsIWidgetで共有しているプラットフォームではnsIDeviceContextが現在のディスプレイを取得するのに失敗するようになり、結果、プライマリモニタに常にメニュー等が展開される、という状況になっていました。

nsIDeviceContextに保存するネイティブウインドウへのポインタをNS_NATIVE_WIDGETのものから、NS_NATIVE_WINDOWのものに変更し、更にこれをトップレベルウインドウのものを常に使うようにしています。これで、問題はひとまず隠蔽することができました。

そう、おそらくこの修正は正しくありませんが、十分なものだと思われます。多くのハッカーが本家のバグでコメントをつけてくれていますが、結局、誰もこのバグの本質は理解できていません。ですが、バグの重要性から、このパッチは間もなく1.9.1 branchにも降ろされる予定です。

ちなみにこの変更で、nsIScreenManager::screenForNativeWidgetの仕様が大きな変更を受けています(見た目に変更が無いのがタチ悪いですが)。このメソッドは[noscript]なのでほとんどの拡張作者には関係無いですが、バイナリのモジュールを持つ、特殊な拡張や、Geckoを埋め込んでこのAPIを利用している場合かつ、それがMac上で動作するものである場合は影響を受けます。Cocoaでは、このポインタはNSViewから、NSWindowに変更されているためです。もし不明な点があればIRCかメールで直接私にコンタクトをとって確認してください。

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

bug 6574を含むエントリ