Simpler heuristic for handling touch-generated mouse events (disable handling of mouse events upon receipt of a touch event until a specified number of mousemove events have been received).

This commit is contained in:
Michael Jumper
2012-07-30 15:00:45 -07:00
parent 3e8d14e699
commit e90eec79e4

View File

@@ -55,6 +55,12 @@ Guacamole.Mouse = function(element) {
*/ */
var guac_mouse = this; var guac_mouse = this;
/**
* The number of mousemove events to require before re-enabling mouse
* event handling after receiving a touch event.
*/
this.touchMouseThreshold = 3;
/** /**
* The current mouse state. The properties of this state are updated when * The current mouse state. The properties of this state are updated when
* mouse events fire. This state object is also passed in as a parameter to * mouse events fire. This state object is also passed in as a parameter to
@@ -95,37 +101,10 @@ Guacamole.Mouse = function(element) {
this.onmousemove = null; this.onmousemove = null;
/** /**
* Zero-delay timeout set when mouse events are fired, and canceled when * Counter of mouse events to ignore. This decremented by mousemove, and
* touch events are detected, in order to prevent touch events registering * while non-zero, mouse events will have no effect.
* as mouse events (some browsers will do this).
*/ */
var deferred_mouse_event = null; var ignore_mouse = 0;
/**
* 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) { function cancelEvent(e) {
e.stopPropagation(); e.stopPropagation();
@@ -142,20 +121,16 @@ Guacamole.Mouse = function(element) {
cancelEvent(e); cancelEvent(e);
// If artificial event detected, ignore currently pending events // If ignoring events, decrement counter
if (deferred_mouse_event) if (ignore_mouse) {
ignorePendingMouseEvents(); ignore_mouse--;
if (ignore_mouse)
return; return;
}
guac_mouse.currentState.fromClientPosition(element, e.clientX, e.clientY); guac_mouse.currentState.fromClientPosition(element, e.clientX, e.clientY);
if (guac_mouse.onmousemove) if (guac_mouse.onmousemove)
deferred_mouse_event = window.setTimeout(function() { guac_mouse.onmousemove(guac_mouse.currentState);
guac_mouse.onmousemove(guac_mouse.currentState);
deferred_mouse_event = null;
}, 0);
}, false); }, false);
@@ -163,10 +138,7 @@ Guacamole.Mouse = function(element) {
cancelEvent(e); cancelEvent(e);
// If artificial event detected, ignore currently pending events // Do not handle if ignoring events
if (deferred_mouse_event)
ignorePendingMouseEvents();
if (ignore_mouse) if (ignore_mouse)
return; return;
@@ -183,10 +155,7 @@ Guacamole.Mouse = function(element) {
} }
if (guac_mouse.onmousedown) if (guac_mouse.onmousedown)
deferred_mouse_event = window.setTimeout(function() { guac_mouse.onmousedown(guac_mouse.currentState);
guac_mouse.onmousedown(guac_mouse.currentState);
deferred_mouse_event = null;
}, 0);
}, false); }, false);
@@ -194,10 +163,7 @@ Guacamole.Mouse = function(element) {
cancelEvent(e); cancelEvent(e);
// If artificial event detected, ignore currently pending events // Do not handle if ignoring events
if (deferred_mouse_event)
ignorePendingMouseEvents();
if (ignore_mouse) if (ignore_mouse)
return; return;
@@ -214,10 +180,7 @@ Guacamole.Mouse = function(element) {
} }
if (guac_mouse.onmouseup) if (guac_mouse.onmouseup)
deferred_mouse_event = window.setTimeout(function() { guac_mouse.onmouseup(guac_mouse.currentState);
guac_mouse.onmouseup(guac_mouse.currentState);
deferred_mouse_event = null;
}, 0);
}, false); }, false);
@@ -256,8 +219,9 @@ Guacamole.Mouse = function(element) {
cancelEvent(e); cancelEvent(e);
}, false); }, false);
// Ignore all pending mouse events when touch events are the apparent source // Ignore all pending mouse events when touch events are the apparent source
function ignorePendingMouseEvents() { ignore_mouse = guac_mouse.touchMouseThreshold; }
element.addEventListener("touchmove", ignorePendingMouseEvents, false); element.addEventListener("touchmove", ignorePendingMouseEvents, false);
element.addEventListener("touchstart", ignorePendingMouseEvents, false); element.addEventListener("touchstart", ignorePendingMouseEvents, false);
element.addEventListener("touchend", ignorePendingMouseEvents, false); element.addEventListener("touchend", ignorePendingMouseEvents, false);