[gtk/gtk-3-24: 1/2] fix touchscreen events processing in broadway.js




commit ba845fa7b24d08a4b0c9b899632140efd1183ac9
Author: Maxim Zakharov <zakhma muli com au>
Date:   Fri Dec 18 12:02:34 2020 +1100

    fix touchscreen events processing in broadway.js
    
    Makes event listeners active explicitly if supported; corrects
    handling for deleted surfaces preventing javascript errors in
    accessing deleted objects; makes event identifiers unique for
    broadwayd when executing in Chrome on Android.
    
    Partially fixes #1493

 gdk/broadway/broadway.js | 87 +++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 72 insertions(+), 15 deletions(-)
---
diff --git a/gdk/broadway/broadway.js b/gdk/broadway/broadway.js
index b134d85faa..270668c71d 100644
--- a/gdk/broadway/broadway.js
+++ b/gdk/broadway/broadway.js
@@ -1,3 +1,27 @@
+/* check if we are on Android and using Chrome */
+var isAndroidChrome = false;
+{
+    var ua = navigator.userAgent.toLowerCase();
+    if (ua.indexOf("android") > -1 && ua.indexOf("chrom") > -1) {
+       isAndroidChrome = true;
+    }
+}
+/* check for the passive option for Event listener */
+let passiveSupported = false;
+try {
+  const options = {
+    get passive() { // This function will be called when the browser
+                    //   attempts to access the passive property.
+      passiveSupported = true;
+      return false;
+    }
+  };
+
+  window.addEventListener("test", null, options);
+  window.removeEventListener("test", null, options);
+} catch(err) {
+  passiveSupported = false;
+}
 /* Helper functions for debugging */
 var logDiv = null;
 function log(str) {
@@ -10,6 +34,25 @@ function log(str) {
     logDiv.appendChild(document.createTextNode(str));
     logDiv.appendChild(document.createElement('br'));
 }
+/* Helper functions for touch identifier to make it unique on Android */
+var globalTouchIdentifier = Math.round(Date.now() / 1000);
+function touchIdentifierStart(tId)
+{
+    if (isAndroidChrome) {
+       if (tId == 0) {
+           return ++globalTouchIdentifier;
+       }
+       return globalTouchIdentifier + tId;
+    }
+    return tId;
+}
+function touchIdentifier(tId)
+{
+    if (isAndroidChrome) {
+       return globalTouchIdentifier + tId;
+    }
+    return tId;
+}
 
 function getStackTrace()
 {
@@ -223,6 +266,7 @@ function cmdSetTransientFor(id, parentId)
 {
     var surface = surfaces[id];
 
+    if (surface === undefined) return;
     if (surface.transientParent == parentId)
        return;
 
@@ -253,8 +297,9 @@ function moveToHelper(surface, position) {
 
     for (var cid in surfaces) {
        var child = surfaces[cid];
-       if (child.transientParent == surface.id)
+       if (child.transientParent == surface.id) {
            moveToHelper(child, stackingOrder.indexOf(surface) + 1);
+       }
     }
 }
 
@@ -269,6 +314,13 @@ function cmdDeleteSurface(id)
        stackingOrder.splice(i, 1);
     var canvas = surface.canvas;
     canvas.parentNode.removeChild(canvas);
+    if (id == windowWithMouse) {
+       windowWithMouse = 0;
+    }
+    if (id == realWindowWithMouse) {
+       realWindowWithMouse = 0;
+       firstTouchDownId = null;
+    }
     delete surfaces[id];
 }
 
@@ -307,6 +359,7 @@ function cmdRaiseSurface(id)
 {
     var surface = surfaces[id];
 
+    if (surface === undefined) return;
     moveToHelper(surface);
     restackWindows();
 }
@@ -315,6 +368,7 @@ function cmdLowerSurface(id)
 {
     var surface = surfaces[id];
 
+    if (surface === undefined) return;
     moveToHelper(surface, 0);
     restackWindows();
 }
@@ -2481,13 +2535,14 @@ function onMouseWheel(ev)
 }
 
 function onTouchStart(ev) {
-    event.preventDefault();
+    ev.preventDefault();
 
     updateKeyboardStatus();
     updateForEvent(ev);
 
     for (var i = 0; i < ev.changedTouches.length; i++) {
         var touch = ev.changedTouches.item(i);
+       var touchId = touchIdentifierStart(touch.identifier);
 
         var origId = getSurfaceId(touch);
         var id = getEffectiveEventTarget (origId);
@@ -2495,7 +2550,7 @@ function onTouchStart(ev) {
         var isEmulated = 0;
 
         if (firstTouchDownId == null) {
-            firstTouchDownId = touch.identifier;
+            firstTouchDownId = touchId;
             isEmulated = 1;
 
             if (realWindowWithMouse != origId || id != windowWithMouse) {
@@ -2510,52 +2565,54 @@ function onTouchStart(ev) {
             }
         }
 
-        sendInput ("t", [0, id, touch.identifier, isEmulated, pos.rootX, pos.rootY, pos.winX, pos.winY, 
lastState]);
+        sendInput ("t", [0, id, touchId, isEmulated, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState]);
     }
 }
 
 function onTouchMove(ev) {
-    event.preventDefault();
+    ev.preventDefault();
 
     updateKeyboardStatus();
     updateForEvent(ev);
 
     for (var i = 0; i < ev.changedTouches.length; i++) {
         var touch = ev.changedTouches.item(i);
+       var touchId = touchIdentifier(touch.identifier);
 
         var origId = getSurfaceId(touch);
         var id = getEffectiveEventTarget (origId);
         var pos = getPositionsFromEvent(touch, id);
 
         var isEmulated = 0;
-        if (firstTouchDownId == touch.identifier) {
+        if (firstTouchDownId == touchId) {
             isEmulated = 1;
         }
 
-        sendInput ("t", [1, id, touch.identifier, isEmulated, pos.rootX, pos.rootY, pos.winX, pos.winY, 
lastState]);
+        sendInput ("t", [1, id, touchId, isEmulated, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState]);
     }
 }
 
 function onTouchEnd(ev) {
-    event.preventDefault();
+    ev.preventDefault();
 
     updateKeyboardStatus();
     updateForEvent(ev);
 
     for (var i = 0; i < ev.changedTouches.length; i++) {
         var touch = ev.changedTouches.item(i);
+       var touchId = touchIdentifier(touch.identifier);
 
         var origId = getSurfaceId(touch);
         var id = getEffectiveEventTarget (origId);
         var pos = getPositionsFromEvent(touch, id);
 
         var isEmulated = 0;
-        if (firstTouchDownId == touch.identifier) {
+        if (firstTouchDownId == touchId) {
             isEmulated = 1;
             firstTouchDownId = null;
         }
 
-        sendInput ("t", [2, id, touch.identifier, isEmulated, pos.rootX, pos.rootY, pos.winX, pos.winY, 
lastState]);
+        sendInput ("t", [2, id, touchId, isEmulated, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState]);
     }
 }
 
@@ -2572,11 +2629,11 @@ function setupDocument(document)
     document.onkeyup = onKeyUp;
 
     if (document.addEventListener) {
-      document.addEventListener('DOMMouseScroll', onMouseWheel, false);
-      document.addEventListener('mousewheel', onMouseWheel, false);
-      document.addEventListener('touchstart', onTouchStart, false);
-      document.addEventListener('touchmove', onTouchMove, false);
-      document.addEventListener('touchend', onTouchEnd, false);
+       document.addEventListener('DOMMouseScroll', onMouseWheel, passiveSupported ? { passive: false, 
capture: false } : false);
+       document.addEventListener('mousewheel', onMouseWheel, passiveSupported ? { passive: false, capture: 
false } : false);
+       document.addEventListener('touchstart', onTouchStart, passiveSupported ? { passive: false, capture: 
false } : false);
+       document.addEventListener('touchmove', onTouchMove, passiveSupported ? { passive: false, capture: 
false } : false);
+       document.addEventListener('touchend', onTouchEnd, passiveSupported ? { passive: false, capture: false 
} : false);
     } else if (document.attachEvent) {
       element.attachEvent("onmousewheel", onMouseWheel);
     }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]