From d9bda20e59d255be55057db21e7f8060355a3207 Mon Sep 17 00:00:00 2001 From: larissasmith Date: Fri, 7 Jul 2017 16:50:03 -0600 Subject: [PATCH 1/5] 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 ) { From fd15789f6fb851257d59f616d685a888f651e872 Mon Sep 17 00:00:00 2001 From: larissasmith Date: Fri, 7 Jul 2017 17:21:01 -0600 Subject: [PATCH 2/5] Update event assertions. --- test/modules/events.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/modules/events.js b/test/modules/events.js index 7e681d05..8e17d266 100644 --- a/test/modules/events.js +++ b/test/modules/events.js @@ -499,9 +499,9 @@ assessGestureExpectations({ description: 'enter-nonprimarypress-nonprimaryrelease-exit (secondary/right click): ', enterCount: 1, - exitCount: 1, + exitCount: 2, pressCount: 0, - releaseCount: 0, + releaseCount: 1, rightPressCount: 1, rightReleaseCount: 1, middlePressCount: 0, @@ -527,9 +527,9 @@ assessGestureExpectations({ description: 'enter-nonprimarypress-nonprimaryrelease-exit (aux/middle click): ', enterCount: 1, - exitCount: 1, + exitCount: 2, pressCount: 0, - releaseCount: 0, + releaseCount: 1, rightPressCount: 0, rightReleaseCount: 0, middlePressCount: 1, @@ -557,9 +557,9 @@ assessGestureExpectations({ description: 'enter-nonprimarypress-move-nonprimaryrelease-move-exit (secondary/right button drag, release in tracked element): ', enterCount: 1, - exitCount: 1, + exitCount: 2, pressCount: 0, - releaseCount: 0, + releaseCount: 1, rightPressCount: 1, rightReleaseCount: 1, middlePressCount: 0, From c3a65bab38d223442b4cb1bd8efa70a7ae0aeb93 Mon Sep 17 00:00:00 2001 From: larissasmith Date: Mon, 10 Jul 2017 13:54:20 -0600 Subject: [PATCH 3/5] Replace filter with a for loop. --- src/mousetracker.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/mousetracker.js b/src/mousetracker.js index 76518f87..2db54b42 100644 --- a/src/mousetracker.js +++ b/src/mousetracker.js @@ -325,10 +325,15 @@ */ getActivePointersListExceptType: function ( type ) { var delegate = THIS[ this.hash ]; + var listArray = []; - return delegate.activePointersLists.filter(function(pointersList) { - return pointersList.type !== type; - }); + for (var i = 0; i < delegate.activePointersLists.length; ++i) { + if (delegate.activePointersLists[i].type !== type) { + listArray.push(delegate.activePointersLists[i]); + } + } + + return listArray; }, /** From 21f103e95d595389c38000da110bea40d7166184 Mon Sep 17 00:00:00 2001 From: larissasmith Date: Wed, 12 Jul 2017 11:13:10 -0600 Subject: [PATCH 4/5] Revert "Update event assertions." This reverts commit fd15789f6fb851257d59f616d685a888f651e872. --- test/modules/events.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/modules/events.js b/test/modules/events.js index 8e17d266..7e681d05 100644 --- a/test/modules/events.js +++ b/test/modules/events.js @@ -499,9 +499,9 @@ assessGestureExpectations({ description: 'enter-nonprimarypress-nonprimaryrelease-exit (secondary/right click): ', enterCount: 1, - exitCount: 2, + exitCount: 1, pressCount: 0, - releaseCount: 1, + releaseCount: 0, rightPressCount: 1, rightReleaseCount: 1, middlePressCount: 0, @@ -527,9 +527,9 @@ assessGestureExpectations({ description: 'enter-nonprimarypress-nonprimaryrelease-exit (aux/middle click): ', enterCount: 1, - exitCount: 2, + exitCount: 1, pressCount: 0, - releaseCount: 1, + releaseCount: 0, rightPressCount: 0, rightReleaseCount: 0, middlePressCount: 1, @@ -557,9 +557,9 @@ assessGestureExpectations({ description: 'enter-nonprimarypress-move-nonprimaryrelease-move-exit (secondary/right button drag, release in tracked element): ', enterCount: 1, - exitCount: 2, + exitCount: 1, pressCount: 0, - releaseCount: 1, + releaseCount: 0, rightPressCount: 1, rightReleaseCount: 1, middlePressCount: 0, From 0bded9f8e17b46f6647b7e0281eca5269dc3b6f2 Mon Sep 17 00:00:00 2001 From: larissasmith Date: Wed, 12 Jul 2017 11:21:52 -0600 Subject: [PATCH 5/5] Correct docs and add check for contact count. --- src/mousetracker.js | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/mousetracker.js b/src/mousetracker.js index 2db54b42..72a1addc 100644 --- a/src/mousetracker.js +++ b/src/mousetracker.js @@ -318,12 +318,12 @@ }, /** - * Returns {Array.} excluding the given pointer device type + * Returns the {@link OpenSeadragon.MouseTracker.GesturePointList|GesturePointList} for all but the given pointer device type. * @function * @param {String} type - The pointer device type: "mouse", "touch", "pen", etc. - * @returns {Array.} + * @returns {Array.} */ - getActivePointersListExceptType: function ( type ) { + getActivePointersListsExceptType: function ( type ) { var delegate = THIS[ this.hash ]; var listArray = []; @@ -2053,18 +2053,21 @@ gPointCount = pointsList.getLength(), abortGPoints = []; - for ( i = 0; i < gPointCount; i++ ) { - abortGPoints.push( pointsList.getByIndex( i ) ); - } + // Check contact count for hoverable pointer types before aborting + if (pointsList.type === 'touch' || pointsList.contacts > 0) { + for ( i = 0; i < gPointCount; i++ ) { + abortGPoints.push( pointsList.getByIndex( i ) ); + } - if ( abortGPoints.length > 0 ) { - // 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, pointsList.type ); - // simulate touchleave/mouseout - updatePointersExit( tracker, event, abortGPoints ); + if ( abortGPoints.length > 0 ) { + // 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, pointsList.type ); + // simulate touchleave/mouseout + updatePointersExit( tracker, event, abortGPoints ); + } } } @@ -2735,7 +2738,7 @@ // 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); + var otherPointsLists = tracker.getActivePointersListsExceptType(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