Neil's Place

August 27, 2009

Mouse Capturing

Filed under: Mozilla — enndeakin @ 11:49 pm

I have been working on adding a mouse capturing API, mostly compatible with the IE API. This means that when the mouse button is pressed on an element, you can trap the mouse movement and redirect the movement events to this element instead. This mechanism appears in Mozilla in a number of places already, although there is currently no public way of doing this. For example, try clicking on a scrollbar thumb and dragging it. Notice how when the pointer is moved away from the scrollbar, it continues to move or traps all mouse movement such that other parts of the UI do not respond. When the mouse is released, everything reverts back to normal again. This is used in few other places as well, for example the draggable splitters between columns in a tree view, the splitters between frames and when drag-selecting.

In bug 503943, I am implementing this feature for both XUL applications and web pages.

Using the feature is quite easy:

onmousedown="this.setCapture(false)"

Within a mousedown event handler, just call the setCapture method. This enables capturing on the element until it is either stopped by calling the releaseCapture method, by releasing the mouse button, or if a drag begins. To prevent odd or possibly nasty things from happening, setCapture will only work while processing a mousedown event.

The argument to setCapture specifies whether children of the capturing element will receive mouse events or not. If false, then they do. If true, then only the capturing element receives them. In the former case, you could set capturing on a containing box, yet still handle the mouse as normal inside it.

There are three small incompatibilities with the IE implementation. First, IE allows setCapture to be called at any time and not just when a mouse button is pressed down. This isn’t recommended and usually causes the mouse to go into a funky state where it doesn’t seem to work properly. Naturally, it’s also very easy to abuse this. So Mozilla won’t allow this and instead only allows capturing during a mouse down.

The second difference is that the argument is optional in both IE and Mozilla, but defaults to false in Mozilla, but true in IE. (We’d have to implement some idl changes to change this). It isn’t too much of a burden since you can always supply the argument if this is a problem.

The third difference is that IE has a different event model so compatibility can be affected and can impact what elements seem to receive events.

However, these differences should be minor for normal usage.

Advertisements

3 Comments »

  1. This is very exciting. We really need this feature in Fennec to be able to capture drag motions reliably from XUL code so moving your finger outside of the window doesn’t cause the drag to be aborted. Thanks!

    Comment by Ben Combee — August 28, 2009 @ 4:35 am

  2. cool, will make rather easy now to make Mac OS X-like splitters with a grippy outside of the splitter itself… thanks Neil.

    Comment by Daniel Glazman — September 14, 2009 @ 5:39 pm

  3. Would you replace multiple versions of the code with a global function then, or is this just so dev’s can add more instances?

    Comment by cuz84d — October 15, 2009 @ 1:52 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: