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
* mouse events fire. This state object is also passed in as a parameter to
* the handler of any mouse events.
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.
+ * Counter of mouse events to ignore. This decremented by mousemove, and
+ * while non-zero, mouse events will have no effect.
*/
- 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);
-
- }
+ var ignore_mouse = 0;
function cancelEvent(e) {
e.stopPropagation();
cancelEvent(e);
- // If artificial event detected, ignore currently pending events
- if (deferred_mouse_event)
- ignorePendingMouseEvents();
-
- if (ignore_mouse)
+ // If ignoring events, decrement counter
+ if (ignore_mouse) {
+ ignore_mouse--;
return;
+ }
guac_mouse.currentState.fromClientPosition(element, e.clientX, e.clientY);
if (guac_mouse.onmousemove)
- deferred_mouse_event = window.setTimeout(function() {
- guac_mouse.onmousemove(guac_mouse.currentState);
- deferred_mouse_event = null;
- }, 0);
+ guac_mouse.onmousemove(guac_mouse.currentState);
}, false);
cancelEvent(e);
- // If artificial event detected, ignore currently pending events
- if (deferred_mouse_event)
- ignorePendingMouseEvents();
-
+ // Do not handle if ignoring events
if (ignore_mouse)
return;
}
if (guac_mouse.onmousedown)
- deferred_mouse_event = window.setTimeout(function() {
- guac_mouse.onmousedown(guac_mouse.currentState);
- deferred_mouse_event = null;
- }, 0);
+ guac_mouse.onmousedown(guac_mouse.currentState);
}, false);
cancelEvent(e);
- // If artificial event detected, ignore currently pending events
- if (deferred_mouse_event)
- ignorePendingMouseEvents();
-
+ // Do not handle if ignoring events
if (ignore_mouse)
return;
}
if (guac_mouse.onmouseup)
- deferred_mouse_event = window.setTimeout(function() {
- guac_mouse.onmouseup(guac_mouse.currentState);
- deferred_mouse_event = null;
- }, 0);
+ guac_mouse.onmouseup(guac_mouse.currentState);
}, false);
cancelEvent(e);
}, false);
-
// 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("touchstart", ignorePendingMouseEvents, false);
element.addEventListener("touchend", ignorePendingMouseEvents, false);