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

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

もずはっく日記(2011年5月)

2011年5月19日

Bug-org 605648 Support high resolution scrolling on Windows
初回投稿日時: 2011年05月19日19時50分58秒
カテゴリ: Mozilla Core Mozilla6 バグ修正
SNS: (list)

WindowsでVista以降、WM_MOUSEWHEELWM_MOUSEHWHEELのデルタ値が基準の120よりも小さい値をマウスのユーティリティが利用できるようになりました。このため、例えば1回のホイールイベントで0.5行だけスクロールする、といったイベントが利用できるようになりました。しかし、Geckoでは最低、1行分のデルタ値がたまったときに初めてスクロールを行っていました。

今回、Logitech (日本ではLogicool)のマウス・キーボードチームのマネージャの方からの要請で、彼らのドライバの精度に十分に対応できるように修正しました。

Macでは以前から、トラックパッドのスクロールイベントはOSからピクセル単位で発生していたため、Gecko内部のホイールイベントに、ピクセルスクロール、というものがありました。本格的に小数の精度でスクロールする処理に対応すると作業量が多いので、ひとまず、これを利用したアドホックなやり方で対応しようというのが今回の修正のテーマでしたが、ここに色々と落とし穴があって、現在もregression対応に追われています。

どのように実装したのかというと、小さなデルタ値で上記メッセージを受け取ったら、ひとまずそれが、何行分のスクロールになるのかを小数込みで計算します。このとき、1行以上であれば、その行数分のホイールイベントを発行します。そして、1未満の小数部分を未送信のデルタ値として保存しておきます。

この内部イベントの生成時に、スクロールターゲットの行高等を確認し、ネイティブイベントのデルタ値で何ピクセルスクロールすべきなのかを、やはり小数を含めて計算し、ピクセルスクロールイベントを生成します。当然、余った1ピクセル未満の端数は内部で保存しておきます。

実際のスクロールは、通常はピクセルスクロールイベントで行われます。XULのツリー等、行単位でしかスクロールできない要素は、ピクセルスクロールは無視し、従来からあるホイールスクロールイベントを利用します。

そして、それ以降に来るネイティブイベントは、保存してある端数を考慮して同様に処理していきます。

これにより、高精度なホイールイベントを生成するマウスを持っている方は、スムーズスクロールを有効にしなくても、今までよりもなめらかなスクロールが行える様になりました。しかし、副作用として当然、それだけ再描画回数が増えるのでスクロール時の負荷は高くなっています。

マイクロソフトのマウスでは設定値にもよりますが、あまり修正前と動作に違いはありません。また、OS標準のドライバをそのまま利用する安価なマウスでも効果はありません。Logitech (日本ではLogicool)のSetPoint 6.20以降だとかなり精度の高い数字でイベントを生成するので効果があります。ただし、同じLogitech (日本ではLogicool)製のマウスでもゲーミングマウスは高精度なイベントを生成しませんのでご注意ください。

上記の解説の通り、Webコンテンツ作者から見た場合にほとんど動作に差異は無いと思われますが、DOMMouseScrollイベントと、スクロールのlistenerを併用している場合、処理順序が変わることになりますのでご注意ください。

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

bug-org 605648を含むエントリ