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

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

もずはっく日記(2015年10月)

2015年10月31日

Bug-org 376679 WM_MOUSEWHEEL and WM_MOUSEHWHEEL messages should be delivered to windowless plugins
初回投稿日時: 2015年10月31日11時22分13秒
カテゴリ: Flash Mozilla Core Mozilla44 plugin Windows バグ修正
SNS: (list)

Windowsでは、windowlessプラグインに対してWM_MOSUEWHEELメッセージや、WM_MOUSEHWHEELメッセージが送信されていないため、windowlessプラグイン上でマウスホイールが使えないというバグです。

調べてみると、そもそも、WidgetWheelEventにネイティブのメッセージをそのまま挿入していませんでした。しかし、単純にこれを行えば修正できるという話でもありません。なぜならGeckoは高解像度スクロールに完全に対応しているため、WidgetWheelEventWM_MOSUEWHEELWM_MOUSEHWHEELを受信した時に必ず送信している訳ではないからです(小数の端数による問題のため)。また、Flash Playerやその他のプラグインも高解像度スクロールに完全に対応しているのか怪しいという点もあります。少なくとも昔、Logitechのエンジニアからの要請でGeckoに高解像度スクロールを実装した際にテストした時には、当時のFlash Playerは非対応でした。

そこで、今回はトリックを使って(この点に関しては)簡単に実装してしまうことにしました。

WidgetWheelEventには、DOMMouseScrollイベントの発火に利用するためのlineOrPageDeltaXlineOrPageDeltaYというメンバがあります。これらは、それぞれの方向へのスクロール量が整数で表現できるようになった時にだけ値がセットされます。例えばWindowsの場合、0.5行ずつのWM_MOUSEWHEELメッセージが連続して来た場合、最初のWidgetWheelEvent::lineOrPageDelatYは1で、二つ目は0、三つ目は再び1、となり、delta値の合計とつじつまが合うようになっています。

これを利用し、この値からWM_MOUSEWHEELメッセージやWM_MOUSEHWHEELメッセージのwParamを計算することで常に、整数行のスクロールが発生するデルタ値のメッセージをwindowlessプラグインに対して送信するようにし、互換性問題を低くしています(ひょっとするとWHEEL_DELTA値で送信しないとスクロールが早すぎるという古くて、当時でも間違っていた実装方法のままのプラグインもあるかもしれませんが……)。

ただし、この修正だけだと、マウスホイールでページ全体をスクロール中にwindowlessプラグインがカーソルの下へ移動してくると、全てのマウスホイールイベントをそのwindowlessプラグインに消費されてしまいます。つまり、スクロールが止まってしまうというバグが発生します。これを防ぐために、windowlessプラグインにマウスホイールのメッセージを送信するのはeWheelイベントのデフォルトアクションという扱いにすることにしました。これにより、マウスホイールトランザクションが活用可能になりますので、直前のスクロールが優先されることになります。

ただし、マウスホイールトランザクションで救えないケース、例えばwindowlessプラグイン上でマウスホイールの操作を開始した場合には、そのwindowlessプラグインが実際にホイールを処理しているか否かに関わらず、そのプラグインに消費されてしまいます。つまり、見た目からページ全体のスクロールを期待しているとバグっているように見えます。しかし、これは別プロセスで動くwindowlessプラグインからホイールの処理が必要だったかどうか、その結果を受けとる仕組みが存在しないので解決不能な問題です。

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

bug-org 376679を含むエントリ