Use event-queue heuristics to detect and ignore mouse events caused by touch events.

This commit is contained in:
Michael Jumper
2012-07-29 17:13:33 -07:00
parent 50567d401b
commit 2f6dbde5da

View File

@@ -94,6 +94,39 @@ Guacamole.Mouse = function(element) {
*/
this.onmousemove = null;
/**
* Zero-delay timeout set when mouse events are fired, and canceled when
* touch events are detected, in order to prevent touch events registering
* as mouse events (some browsers will do this).
*/
var deferred_mouse_event = null;
/**
* Flag which, when set to true, will cause all mouse events to be
* ignored. Used to temporarily ignore events when generated by
* touch events, and not by a mouse.
*/
var ignore_mouse = false;
/**
* Forces all mouse events to be ignored until the event queue is flushed.
*/
function ignorePendingMouseEvents() {
// Cancel deferred event
if (deferred_mouse_event) {
window.clearTimeout(deferred_mouse_event);
deferred_mouse_event = null;
}
// Ignore all other events until end of event loop
ignore_mouse = true;
window.setTimeout(function() {
ignore_mouse = false;
}, 0);
}
function cancelEvent(e) {
e.stopPropagation();
if (e.preventDefault) e.preventDefault();
@@ -122,7 +155,10 @@ Guacamole.Mouse = function(element) {
guac_mouse.currentState.y -= parent.offsetTop - documentScrollTop;
if (guac_mouse.onmousemove)
guac_mouse.onmousemove(guac_mouse.currentState);
deferred_mouse_event = window.setTimeout(function() {
guac_mouse.onmousemove(guac_mouse.currentState);
deferred_mouse_event = null;
}, 0);
}
@@ -136,6 +172,13 @@ Guacamole.Mouse = function(element) {
cancelEvent(e);
// If artificial event detected, ignore currently pending events
if (deferred_mouse_event)
ignorePendingMouseEvents();
if (ignore_mouse)
return;
moveMouse(e.clientX, e.clientY);
}, false);
@@ -144,6 +187,13 @@ Guacamole.Mouse = function(element) {
cancelEvent(e);
// If artificial event detected, ignore currently pending events
if (deferred_mouse_event)
ignorePendingMouseEvents();
if (ignore_mouse)
return;
switch (e.button) {
case 0:
guac_mouse.currentState.left = true;
@@ -157,7 +207,10 @@ Guacamole.Mouse = function(element) {
}
if (guac_mouse.onmousedown)
guac_mouse.onmousedown(guac_mouse.currentState);
deferred_mouse_event = window.setTimeout(function() {
guac_mouse.onmousedown(guac_mouse.currentState);
deferred_mouse_event = null;
}, 0);
}, false);
@@ -165,6 +218,13 @@ Guacamole.Mouse = function(element) {
cancelEvent(e);
// If artificial event detected, ignore currently pending events
if (deferred_mouse_event)
ignorePendingMouseEvents();
if (ignore_mouse)
return;
switch (e.button) {
case 0:
guac_mouse.currentState.left = false;
@@ -178,7 +238,10 @@ Guacamole.Mouse = function(element) {
}
if (guac_mouse.onmouseup)
guac_mouse.onmouseup(guac_mouse.currentState);
deferred_mouse_event = window.setTimeout(function() {
guac_mouse.onmouseup(guac_mouse.currentState);
deferred_mouse_event = null;
}, 0);
}, false);
@@ -217,6 +280,12 @@ Guacamole.Mouse = function(element) {
cancelEvent(e);
}, false);
// Ignore all pending mouse events when touch events are the apparent source
element.addEventListener("touchmove", ignorePendingMouseEvents, false);
element.addEventListener("touchstart", ignorePendingMouseEvents, false);
element.addEventListener("touchend", ignorePendingMouseEvents, false);
// Scroll wheel support
function mousewheel_handler(e) {