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

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

もずはっく日記(2014年8月)

2014年8月30日

Bug-org 826657 [TSF] Implement ITfMouseTrackerACP
初回投稿日時: 2014年08月30日17時09分58秒
カテゴリ: Mozilla Core Mozilla34 TSF Windows バグ修正
SNS: (list)

TSFでは、TIPは、マウスのイベントを受け取りたい場合、ITextStoreに、マウスイベントのリスナを登録する必要があります。このバグはそれに、対応しようというバグです。

まず、イベントリスナのインターフェースである、ITfMouseSinkを受け入れるための、ITfMouseTrackerACPインターフェースを単純に、nsTextStoreに実装しました。

ただし、実際の登録・削除処理は若干、面倒なことに、任意の個数のITfMouseSinkを同時にインストール可能です。これは、MSDNでは名言されていませんが、ITfMouseTrackerACP::AdviseSink()で登録時にDWORD値のCookieを返し、ITfMouseTrackerACP::UnadviseSink()を呼び出す時には、そのCookie値のみで削除するITfMouseSinkを指定しようとしている形になっていることから、DWORDで表現できる個数程度は登録可能である必要があるということが伺えます。現に、他のオープンソースソフトウェアのソースコードを調査しましたが、やはり、複数のITfMouseSinkを同時にインストールできるようになっていました。

nsTextStore::MouseTackerクラスを新設し、これをnsTArrayで配列として管理し、各インスタンスには、Cookie値、ITfMouseSinkの実装へのポインタ、マウスイベントを受け取りたい、文字列の範囲を保存しています。現在、Cookie値は配列のインデックスと同値ですが、将来的に、フットプリントが問題になるようなら、配列から削除しても処理が破綻しないように、二重管理する形にしています。

次に、マウスのボタンが押されたときと離された時に、その座標に文字があるかどうか調査し、無ければ無視、あれば、その文字のどの位置でイベントが発生したのかをITfMouseSink::OnMouseEvent()に通知しなくてはいけません。

これまでの実装(IMM等)では、widgetから、NS_QUERY_CONTENT_CHARACTER_AT_POINTイベントを送信し、カーソル位置の情報を取得していましたが、このままでは、現在開発が進んでいる、e10s(Firefoxのマルチプロセス化)には対応できません。なぜなら、ネイティブイベントは、chromeを管理する、親プロセスが受け取りますが、contentは子プロセスにあります。子プロセスの情報を取得するには、同期通信で情報を取得する必要がありますが、子プロセスが処理落ちやハングアップしている時に、chromeプロセスが巻き添えを食わないように、これは禁止されています。

そこで、全く逆のアプローチをとることにしました。content側には現在、フォーカスを持ったエディタの状態を監視し、nsIWidget::NotifyIME()で様々なことを通知している、IMEContentObserverが居ます。エディタ上の文字でマウスのボタンが押されたとき、もしくは、話された時に、ここから、新しい通知を同期通信で出せば、widget側でIMEにマウスイベントを通知できますし、IMEContentObserverは、そのイベントがIMEによって消費されたかどうかを確認することもできます。

どのような通知が行われているのかは、nsIWidget::IMENotification::mMouseButtonEventDataを参照してください。

このアプローチにより、各プラットフォームのIMEイベントハンドラごとに、似たような処理を書かなくて済むようになった上に、e10sにも対応可能なので、かなり、成功した修正になったと思っています。

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

bug-org 826657を含むエントリ

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

このエントリを参照しているURIはありません。