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

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

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

2010年10月8日

Bug-org 597981 When Google VKB is opened, Key-Repeat does not work! (On latest gtk2 platforms, keydown events are not dispatched by auto repeat)
初回投稿日時: 2010年10月08日15時38分09秒
最終更新日時: 2010年10月08日16時53分26秒
カテゴリ: Mozilla Core バグ修正
SNS: (list)

言葉足らずでかなり理解が怪しくなりそうなので、大きく変更・追記しました。

最近のGTK2上でキーボードのキーを押しっぱなしにすると、DOMキーイベントが

  1. keydown
  2. keypress
  3. keypress
  4. ...
  5. keyup

という順序で生成され、keydownイベントを期待しているWebアプリが動かなくなっている、というバグです。

調べてみると、Ubuntu 9.4では、

  1. keydown
  2. keypress
  3. keyup
  4. keydown
  5. keypress
  6. keyup
  7. ...

と、リピート入力時にも、keydownkeypresskeyupがワンセットで生成されていました。

GTK2のネイティブには、key pressイベントと、key releaseイベントのみがあります。Geckoはkey pressイベントを受け取ると、コンテンツに対して、keydownイベントと、keypressイベントを生成しています。

DOM3でキーイベントの発生順序が定義されていなかった時に、Linux版のGeckoは、現在と同じ、

  1. keydown
  2. keypress
  3. keypress
  4. ...
  5. keyup

という順序になるように、keydownイベントを最初のネイティブのkey pressイベントでしか生成しないように、あえて制限を行っていました。

ところが、Ubuntu 9.4当時のGTK2は、リピート時に、key pressイベントだけではなく、key upイベントもワンセットで送信するように挙動を変更していました。これにより、keydownをリピートごとに生成しないようにする、というコードが動くことが無くなっていました。

この時点でGeckoの開発者としてはバグに気づくべきでした。想定していた通りのイベントがプラットフォームからは来なくなっていましたので。しかし、残念ながらこれを自動でテストする手段はまだ見つかっていませんので、この問題は発見されていませんでした。

ここで、Web開発者の視点に立ってみると、DOM3で最近提案されたキーイベントの順序とは異なり、余計なkeyupが来るものの、keypressイベントの前には常にkeydownイベントが必ず発生するようにGeckoが修正されたかのように見えます。

ですが、Ubuntu 9.10以降のGTK2では、リピート時に再び、key upイベントを送信してこなくなりました。このため、Geckoのkeydownイベントの抑制コードが再び動くようになりました。これにより、DOM3のイベント順序案からさらに離れた、昔のイベントの発生順序に戻ってしまい、DOM3を意識したWebアプリケーションの動作に悪影響が出ていたわけです。

今回の修正で、Windows版と同様、DOM3の仕様案通りに、

  1. keydown
  2. keypress
  3. keydown
  4. keypress
  5. ...
  6. keyup

という順序でkeypressイベントの前には必ずkeydownイベントがリピートされるようになりました。

なお、Mac版の修正はBug-org 599887で承認待ちになっています。

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

bug-org 597981を含むエントリ

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

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