From d9bda20e59d255be55057db21e7f8060355a3207 Mon Sep 17 00:00:00 2001 From: larissasmith Date: Fri, 7 Jul 2017 16:50:03 -0600 Subject: [PATCH] Fix more issues with tracking multiple pointers. --- src/mousetracker.js | 71 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 13 deletions(-) diff --git a/src/mousetracker.js b/src/mousetracker.js index d81f5561..76518f87 100644 --- a/src/mousetracker.js +++ b/src/mousetracker.js @@ -317,6 +317,20 @@ return this; }, + /** + * Returns {Array.} excluding the given pointer device type + * @function + * @param {String} type - The pointer device type: "mouse", "touch", "pen", etc. + * @returns {Array.} + */ + getActivePointersListExceptType: function ( type ) { + var delegate = THIS[ this.hash ]; + + return delegate.activePointersLists.filter(function(pointersList) { + return pointersList.type !== type; + }); + }, + /** * Returns the {@link OpenSeadragon.MouseTracker.GesturePointList|GesturePointList} for the given pointer device type, * creating and caching a new {@link OpenSeadragon.MouseTracker.GesturePointList|GesturePointList} if one doesn't already exist for the type. @@ -1201,6 +1215,30 @@ } } return null; + }, + + /** + * @function Increment this pointer's contact count. + * It will evaluate whether this pointer type is allowed to have multiple contacts. + */ + addContact: function() { + ++this.contacts; + + if (this.contacts > 1 && (this.type === "mouse" || this.type === "pen")) { + this.contacts = 1; + } + }, + + /** + * @function Decrement this pointer's contact count. + * It will make sure the count does not go below 0. + */ + removeContact: function() { + --this.contacts; + + if (this.contacts < 0) { + this.contacts = 0; + } } }; @@ -2005,7 +2043,7 @@ * @private * @inner */ - function abortTouchContacts( tracker, event, pointsList ) { + function abortContacts( tracker, event, pointsList ) { var i, gPointCount = pointsList.getLength(), abortGPoints = []; @@ -2015,12 +2053,12 @@ } if ( abortGPoints.length > 0 ) { - // simulate touchend + // simulate touchend/mouseup updatePointersUp( tracker, event, abortGPoints, 0 ); // 0 means primary button press/release or touch contact // release pointer capture pointsList.captureCount = 1; - releasePointer( tracker, 'touch' ); - // simulate touchleave + releasePointer( tracker, pointsList.type ); + // simulate touchleave/mouseout updatePointersExit( tracker, event, abortGPoints ); } } @@ -2043,7 +2081,7 @@ if ( pointsList.getLength() > event.touches.length - touchCount ) { $.console.warn('Tracked touch contact count doesn\'t match event.touches.length. Removing all tracked touch pointers.'); - abortTouchContacts( tracker, event, pointsList ); + abortContacts( tracker, event, pointsList ); } for ( i = 0; i < touchCount; i++ ) { @@ -2213,7 +2251,7 @@ function onTouchCancel( tracker, event ) { var pointsList = tracker.getActivePointersListByType('touch'); - abortTouchContacts( tracker, event, pointsList ); + abortContacts( tracker, event, pointsList ); } @@ -2690,6 +2728,14 @@ } } + // Some pointers may steal control from another pointer without firing the appropriate release events + // e.g. Touching a screen while click-dragging with certain mice. + var otherPointsLists = tracker.getActivePointersListExceptType(gPoints[ 0 ].type); + for (i = 0; i < otherPointsLists.length; i++) { + //If another pointer has contact, simulate the release + abortContacts(tracker, event, otherPointsLists[i]); // No-op if no active pointer + } + // Only capture and track primary button, pen, and touch contacts if ( buttonChanged !== 0 ) { // Aux Press @@ -2740,7 +2786,7 @@ startTrackingPointer( pointsList, curGPoint ); } - pointsList.contacts++; + pointsList.addContact(); //$.console.log('contacts++ ', pointsList.contacts); if ( tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) { @@ -2880,11 +2926,10 @@ } // A primary mouse button may have been released while the non-primary button was down - if (pointsList.contacts > 0 && pointsList.type === 'mouse') { - // Stop tracking the mouse; see https://github.com/openseadragon/openseadragon/pull/1223 - pointsList.contacts--; - return true; - } + var otherPointsList = tracker.getActivePointersListByType("mouse"); + // Stop tracking the mouse; see https://github.com/openseadragon/openseadragon/pull/1223 + abortContacts(tracker, event, otherPointsList); // No-op if no active pointer + return false; } @@ -2913,7 +2958,7 @@ if ( wasCaptured ) { // Pointer was activated in our element but could have been removed in any element since events are captured to our element - pointsList.contacts--; + pointsList.removeContact(); //$.console.log('contacts-- ', pointsList.contacts); if ( tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) {