summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Mannehed <samuel@cendio.se>2017-02-14 16:20:18 +0100
committerSamuel Mannehed <samuel@cendio.se>2017-02-16 13:59:22 +0100
commit1658466579ee638aa29aaa7adfc18bb64348737c (patch)
tree12f29ad56857336e7868b2c32c2c920bbd4ca785
parent0ee5ca6ebe3ff8fbb8112cd7e235fdbc98ff32bb (diff)
downloadnovnc-1658466579ee638aa29aaa7adfc18bb64348737c.tar.gz
Improve setCapture polyfill
Fix some corner cases. Fixes issue #773
-rw-r--r--core/util.js27
1 files changed, 26 insertions, 1 deletions
diff --git a/core/util.js b/core/util.js
index e73eb9d..30f75e1 100644
--- a/core/util.js
+++ b/core/util.js
@@ -531,6 +531,14 @@ Util._captureProxy = function (e) {
Util._captureElem.dispatchEvent(newEv);
Util._captureRecursion = false;
+ // Avoid double events
+ e.stopPropagation();
+
+ // Respect the wishes of the redirected event handlers
+ if (newEv.defaultPrevented) {
+ e.preventDefault();
+ }
+
// Implicitly release the capture on button release
if ((e.type === "mouseup") || (e.type === "touchend")) {
Util.releaseCapture();
@@ -547,6 +555,10 @@ Util.setCapture = function (elem) {
elem.addEventListener('touchend', Util.releaseCapture);
} else {
+ // Release any existing capture in case this method is
+ // called multiple times without coordination
+ Util.releaseCapture();
+
// Safari on iOS 9 has a broken constructor for TouchEvent.
// We are fine in this case however, since Safari seems to
// have some sort of implicit setCapture magic anyway.
@@ -572,6 +584,10 @@ Util.setCapture = function (elem) {
captureElem.style.display = "none";
document.body.appendChild(captureElem);
+ // This is to make sure callers don't get confused by having
+ // our blocking element as the target
+ captureElem.addEventListener('contextmenu', Util._captureProxy);
+
captureElem.addEventListener('mousemove', Util._captureProxy);
captureElem.addEventListener('mouseup', Util._captureProxy);
@@ -598,8 +614,17 @@ Util.releaseCapture = function () {
document.releaseCapture();
} else {
+ if (!Util._captureElem) {
+ return;
+ }
+
+ // There might be events already queued, so we need to wait for
+ // them to flush. E.g. contextmenu in Microsoft Edge
+ //
+ // FIXME: What happens if setCapture is called before this fires?
+ window.setTimeout(function() { Util._captureElem = null; });
+
var captureElem = document.getElementById("noVNC_mouse_capture_elem");
- Util._captureElem = null;
captureElem.style.display = "none";
window.removeEventListener('mousemove', Util._captureProxy);