ISSUE-33 and ISSUE-56: multiple device events and mousewheel events

This is a proposition to handle multiple device in DOM3EV as stated in 
ISSUE-33. It also resolves the trackpad emulation of two wheels as 
stated in ISSUE-56.

Some example of multiple device include:

- a trackpad that emulates two wheels (one vertical and one horizontal)
- two mice connected to the same computer
- a multipoint touch screen such as the DiamondTouch table tracking 
several fingers on a surface

A first requirement of that proposition is that simple configurations 
with one device of each type (eg. 1 mouse, 1 wheel) have the same 
behaviour as usual. This implies for instance to keep existing UIEvent 
events such as "mousewheel" and "mousemove" with their existing slots.

A second requirement is that more complex configurations (eg. two mice, 
a trackpad emulating two wheels) still work with existing code written 
for simple configurations with one device of each type.

A third requirement is that it is easy for the application author to 
check for events involving multiple device of the same type at the same 
time. This is sometimes called event coalescing (eg. two wheels moving 
at the same time to describe a diagonal movement).

The proposition is to attribute a virtual device number to each device 
of a same type (eg. with a trackpad emulating a vertical and horizontal 
wheels, the vertical wheel would get virtual device number 0, and the 
horizontal one virtual device number 1; eg. with two mice the principal 
mouse would get virtual device number 0 and secondary mouse would get 
virtual device number 1, etc.).

Then, the proposition is to fire multiple events at the same time when 
several device of the same type are manipulated together (eg. for a 
trackpad emulating two wheels the UA would send a "mousewheel" and a 
"mousewheel" -possibly renamed "mousewheelx"- events in case of a 
movement on the diagonal). In the UIEvent class the proposition is to 
add a "related" slot containing an array that point to each event 
emitted. The "related" array is indexed by virtual device number. If 
the corresponding device didn't participate to the mutliple device 
event, then its entry is set to null.

To simplify access to the "related" array, there would be a "vmask" bit 
mask in the event that specifies which virtual devices are part of the 
multiple device event. This "vmask" bit mask is similar to the bit mask 
used in Unix select system call to check file descriptors ready for 
data read/write. The total number of virtual devices of a type would 
also be indicated in a "vtotal" slot.

In summary, the proposition adds the following slots to the UIEvent 
type:

- vdevice: number of the virtual device, if there is only one device of 
a type connected this number is always 0 (eg. 1 mouse or 1 wheel)

- vmask: a bit mask indicating which devices of a given type have fired 
an event at the same time (this supposes coalescing events of the same 
type is done at UA level)

- vtotal: total number of devices able to emit that kind of event (ie. 
this is the maximum size of the related array)

- related: an array that contains all the events that were fired at the 
same time indexed by vdevice number (or null if the corresponding 
vdevice didn't emit an event at that time); thus the following 
invariant holds true at anytime in an event instance "related[vdevice] 
= self"

For a classical mouse move event in a configuration with 1 mouse, the 
value of these extra slots would be:

- vdevice = 0
- vmask = 0b1 (binary mask, 1 in decimal)
- vtotal = 1
- related[0] = the event ( self )

For a trackpad emulating two mice there would be two events emitted 
(let's suppose they have different names "mousewheel" and 
"mousewheelx") with the following extra slots:

"mousewheel":

- vdevice = 0
- vmask = 0b11 (binary mask, 3 in decimal)
- vtotal = 2
- related[0] = the "mousewheel" event ( self )
- related[1] = the "mousewheelx" event below

"mousewheelx":

- vdevice = 1
- vmask = 0b11 (binary mask, 3 in decimal)
- vtotal = 2
- related[0] = the "mousewheel" event above
- related[1] = the "mousewheelx" event ( self )

The advantages of that proposition are that:

- applications that don't care with multiple device events can just 
perform as usual (all the other slots in UIEvent are unchanged)

- it is extensible (there can ba as many device of the same type 
connected or emulated, this just requires to add more entries in the 
related array)

The inconvenient of that proposition is that:

- if the event names are not renamed for each virtual device (eg. 
"mousewheelx" for the second wheel instead of "mousewheel", eg. 
"mousemoveII" instead of "mousemove" for the secondary mouse), then an 
application not multiple device aware (ie. that does not check the 
vdevice slot) would receive several time the same event (eg. 
"mousewheel") in case of multiple device events and could possibly over 
handle it

- it doesn't change addEventListener API as the checking for multiple 
device can be done in the event handler with the vdevice event slot in 
the event (unless we decide to give different names to the event 
emitted by different device of the same type, see previous paragraph)

- it doesn't require an introspection API to check for multiple devices 
(although one could be desirable), to know if multiple devices of the 
same type are connected the application can check if the "vtotal" slot 
in events is > 1

- no implementation at that time (although it would be simple to 
implement on top of existing UAs)

Stéphane Sire
---
Research engineer
IntuiLab - http://www.intuilab.com/gallery

Received on Tuesday, 11 April 2006 09:25:55 UTC