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

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

もずはっく日記(2012年6月)

2012年6月11日

Windows版Firefoxのwindowed modeとwindowless modeそれぞれのプラグインの構造
初回投稿日時: 2012年06月11日20時47分22秒
最終更新日時: 2012年06月12日12時17分21秒
カテゴリ: Flash Mozilla Core plugin Windows 雑談
SNS: (list)

知ってる人がどうも少ないっぽいのでちょっと解説を。まずは、『ウインドウ』という用語が分かっていないと話がさっぱり分からないと思うのでその説明から。以下のスクリーンショットはメモ帳の検索ダイアログです。

メモ帳の検索ダイアログのスクリーンショット

一般的にはこのダイアログ全体をひとつのウインドウと呼んだりしますが、Windowsの開発用語では、これはさらに多数のウインドウから構成されていることになります。そのウインドウごとにバラバラにすると以下のようになります。

メモ帳の検索ダイアログの各ウインドウをバラバラにした図

各UI部品それぞれがウインドウで、ウインドウにウインドウが貼り付いてるという形になります。フォーカスはこのウインドウごとに持てる、持てない、という違いがありますが、フォーカスというのはウインドウレベルでの話になります。

さて、Windows版Firefox用のプラグインにはwindowed modeと、windowless modeの二つの動作モードがあります。

Windowed modeの場合、プラグインの表示位置にplugin-container.exeがウインドウを作成し、親のFirefoxのウインドウにそのウインドウを貼り付けます。そして、plugin-container.exe内で動いているプラグインはこのウインドウの上に直接描画したり、さらにウインドウを貼り付けたりします。また、これらのウインドウはフォーカスを持つこともでき、これらの上で発生したイベントを直接処理できます。

Windowless modeの場合、plugin-container.exeはウインドウを作成しません。親のFirefoxのウインドウ自身がイベントを受け取り、その内容を必要があればplugin-container.exe内で動いているプラグインに対してDOMイベント経由で通知を行います。

しかし、ここにややこしい問題が発生します。Windowsではウインドウに描画するにしても、IMEと通信して未確定文字列を取得したり、候補ウインドウの表示位置を指定するにしてもそれぞれのコンテキストを取得してAPIを呼び出さないといけませんが、当然、各コンテキストはプロセスごとに生成されており、他のプロセスが所有するウインドウに関連づけられたコンテキストに対してアクセスすることはできません。

Firefox上でwindowless modeのFlashのエディタでIMEを利用する場合に、キャレット位置に未確定文字列が表示されないのはこれがその理由です。Windowsはアプリが未確定文字列を自分で描画できない場合、Windowsが用意した、独立したウインドウ内に未確定文字列を表示して作業することができるようになっています。そして、最後に確定した文字列のイベントだけをアプリが処理することによって、IMEに対応していないアプリであっても入力だけはかろうじてできるようになっています。

逆に、windowed modeのFlashのエディタでは同じプロセスのウインドウに関連づけられたIMEのコンテキストにフルアクセスできるので、未確定文字列の表示も、候補ウインドウの表示も普通のアプリと同じレベルで処理することができているのです。

それぞれのモードを利用している代表的な例では、Youtubeやニコニコ動画はwindowed modeを利用していて、Ustreamは動画部分はwindowed mode、チャット部分は何故かwindowless modeとなっています。

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

関連するかもしれないエントリを発見できませんでしたが、無いとは限りません。

このエントリへのリンク元