Home > Latest topics

Latest topics > ドラッグ&ドロップ中のタイマーを擬似的に再現する

宣伝。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。 以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能! シス管系女子って何!? - 「シス管系女子」特設サイト

ドラッグ&ドロップ中のタイマーを擬似的に再現する - May 03, 2007

Windowsのエクスプローラでは、ファイルなどのドラッグ中にフォルダの上でしばらく待つと、そのフォルダを勝手に開いてくれる。Firefoxのブックマークのフォルダもそういう風になっている。これと同じように、Second Searchの挙動を変えてみよう、と思って色々実験してみた。

目指す挙動は、「検索バーの上に文字列をドラッグしてしばらく待つと、ポップアップが出てきて検索エンジンを選択できる」というもの。

まず最初に思いつくのが、JavaScriptのタイマーを使ってやる方法。でも、Split Browserの実装の解説でも触れたけど、Firefoxではドラッグ&ドロップの最中はJavaScriptのタイマーは(window.setTimeout()window.setInterval()も)一切停止してしまって、ドロップ後にまとめて動き出すようになっている。

もしかしたらXPCOMの方のタイマーなら……と思ってnsITimerを使ってみたけど、これも同じだった。どのタイプのタイマーを設定しても、JavaScriptのタイマーと同じ現象が起こってしまった。

ていうかそもそもの話、「ブックマーク」メニューやブックマークツールバーにおいては、すでにこのような挙動が実現されてるわけで。だったら最初っからそこら辺のソースコードを見るのが早いよね、と。

そういうわけでメニューの定義とかあちこち見ていたら、このあたりの挙動はBookmarksMenuDNDObserverというオブジェクトが受け持っていることが分かった。各メソッドの中身を見ていくと、onDragEnterSetTimerとかonDragExitSetTimerとかいう名前のメソッドがあることに気がついたので、何となく怪しいのでそっちも見てみたら、ようやく謎が解けた。

まず冒頭に書いた、ドラッグ中にすべてのタイマーが止まってしまう問題なんだけど、コードを見てみるとこれはどうやらWindows環境のみの制限らしい。後で試してみたら、確かにLinuxではドラッグ中でもタイマーが動いてくれた。Firefoxのブックマークまわりでも、Windows環境以外では(実質的には、LinuxとかのUnix系だけみたいなんだけど)普通にタイマーを使ってこの挙動を実現しているようだ。

じゃあWindowsではどうしてるのかというと、代わりにdragoverイベントを使っていた。

WindowsでもLinuxでも、オブジェクトをドラッグしていて何らかのXUL要素の上にポインタがある時は、mouseoverイベントの代わりにdragoverが発生する。このdragoverイベントの面白いところは、まるでキーリピートがかかっている時のkeypressイベントのように、ポインタが要素の上にある間は一定の時間間隔で連続してイベントが発生し続けるという点だ(mouseoverもそうだったっけ?)。

そこでFirefoxのコードでは、こういう事を行っている。

  1. まず、dragenterdragexitのイベントが発生した時点で、その時刻をどこかに保持しておく。
  2. dragoverイベントをハンドリングして、ハンドリングした時点での時刻と、dragenterdragexitのイベントが発生した時刻とを比較する。
  3. この時、一定の時間(ブックマークまわりの場合は350ミリ秒でハードコーディングされてる)が経過していなければ何も行わない。一定以上の時間が経過していれば、ポップアップメニューを開く。

あんまりスマートではないけど、現状ではこれ以外に方法は無いようだ。というわけでさっそくSecond Searchでも同じ処理を行うようにしてみたところ、無事Windowsでも望み通りの動作を行えるようになった。めでたしめでたし。

ちなみに、Mac OS上のFirefoxではこの処理が全面的に無効にされてしまっている。検証してないけど、これは、どうがんばっても無理って事なんすかね。

このWindows環境特有の問題はFirefox 3では解消されたようです。

分類:Mozilla > XUL, , , , 時刻:00:42 | Comments/Trackbacks (0) | Edit

Comments/Trackbacks

TrackBack ping me at


の末尾に2020年11月30日時点の日本の首相のファミリーネーム(ローマ字で回答)を繋げて下さい。例えば「noda」なら、「2007-05-03_dragdrop-and-timer.trackbacknoda」です。これは機械的なトラックバックスパムを防止するための措置です。

Post a comment

writeback message: Ready to post a comment.

2020年11月30日時点の日本の首相のファミリーネーム(ひらがなで回答)

Powered by blosxom 2.0 + starter kit
Home

カテゴリ一覧

過去の記事

1999.2~2005.8

最近のコメント

最近のつぶやき