*/
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();
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);
}
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);
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;
}
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);
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;
}
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);
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) {