From d7fa30fd43674b6ee63f89a4bf8ec69573e3bb42 Mon Sep 17 00:00:00 2001 From: Tomasz Sapeta Date: Tue, 4 Oct 2022 14:59:59 +0200 Subject: [PATCH] Update to 2.7.0 --- CHANGELOG.md | 2 +- .../gesturehandler/FlingGestureHandler.kt | 14 +-- .../gesturehandler/GestureHandler.kt | 72 +++++++----- .../GestureHandlerOrchestrator.kt | 105 +++++++++++++----- .../components/gesturehandler/GestureUtils.kt | 10 +- .../gesturehandler/LongPressGestureHandler.kt | 12 +- .../gesturehandler/ManualGestureHandler.kt | 2 +- .../NativeViewGestureHandler.kt | 2 +- .../gesturehandler/PanGestureHandler.kt | 22 ++-- .../gesturehandler/PinchGestureHandler.kt | 26 +++-- .../gesturehandler/RotationGestureHandler.kt | 23 ++-- .../gesturehandler/TapGestureHandler.kt | 20 ++-- .../RNGestureHandlerButtonViewManager.kt | 43 +++++-- .../react/RNGestureHandlerModule.kt | 4 +- .../react/RNGestureHandlerRootHelper.kt | 2 +- apps/bare-expo/package.json | 2 +- apps/bare-sandbox/package.json | 2 +- apps/native-component-list/package.json | 2 +- apps/test-suite/package.json | 2 +- home/package.json | 2 +- ios/Podfile.lock | 4 +- .../RNGestureHandler.podspec.json | 4 +- .../RNGestureHandlerButtonComponentView.mm | 8 +- packages/expo-stories/package.json | 2 +- packages/expo/bundledNativeModules.json | 2 +- 25 files changed, 244 insertions(+), 145 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 932bdee3907c4..77e64477fd3a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ Package-specific changes not released in any SDK will be added here just before - Updated `@stripe/stripe-react-native` from `0.13.1` to `0.18.1` on iOS. ([#19055](https://github.com/expo/expo/pull/19055) by [@tsapeta](https://github.com/tsapeta)) - Updated `@shopify/flash-list` from `1.1.0` to `1.3.0`. ([#19317](https://github.com/expo/expo/pull/19317) by [@kudo](https://github.com/kudo)) - Updated `react-native-webview` from `11.23.0` to `11.23.1`. ([#19375](https://github.com/expo/expo/pull/19375) by [@aleqsio](https://github.com/aleqsio)) -- Updated `react-native-gesture-handler` from `2.5.0` to `2.6.2`. ([#19362](https://github.com/expo/expo/pull/19362) by [@tsapeta](https://github.com/tsapeta)) +- Updated `react-native-gesture-handler` from `2.5.0` to `2.7.0`. ([#19362](https://github.com/expo/expo/pull/19362) by [@tsapeta](https://github.com/tsapeta)) ### 🛠 Breaking changes diff --git a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/FlingGestureHandler.kt b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/FlingGestureHandler.kt index 5ff0dd80acf24..e1bb6fd828b33 100644 --- a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/FlingGestureHandler.kt +++ b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/FlingGestureHandler.kt @@ -63,19 +63,19 @@ class FlingGestureHandler : GestureHandler() { } } - override fun onHandle(event: MotionEvent) { + override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) { val state = state if (state == STATE_UNDETERMINED) { - startFling(event) + startFling(sourceEvent) } if (state == STATE_BEGAN) { - tryEndFling(event) - if (event.pointerCount > maxNumberOfPointersSimultaneously) { - maxNumberOfPointersSimultaneously = event.pointerCount + tryEndFling(sourceEvent) + if (sourceEvent.pointerCount > maxNumberOfPointersSimultaneously) { + maxNumberOfPointersSimultaneously = sourceEvent.pointerCount } - val action = event.actionMasked + val action = sourceEvent.actionMasked if (action == MotionEvent.ACTION_UP) { - endFling(event) + endFling(sourceEvent) } } } diff --git a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/GestureHandler.kt b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/GestureHandler.kt index f99caa3e9b37d..c9602050d117b 100644 --- a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/GestureHandler.kt +++ b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/GestureHandler.kt @@ -4,6 +4,7 @@ import host.exp.expoview.BuildConfig import android.app.Activity import android.content.Context import android.content.ContextWrapper +import android.graphics.PointF import android.graphics.Rect import android.view.MotionEvent import android.view.MotionEvent.PointerCoords @@ -326,7 +327,7 @@ open class GestureHandler + val padLeft = hitSlop[HIT_SLOP_LEFT_IDX] + val padTop = hitSlop[HIT_SLOP_TOP_IDX] + val padRight = hitSlop[HIT_SLOP_RIGHT_IDX] + val padBottom = hitSlop[HIT_SLOP_BOTTOM_IDX] if (hitSlopSet(padLeft)) { left -= padLeft } @@ -603,8 +607,8 @@ open class GestureHandler, event: MotionEvent) { + private fun deliverEventToGestureHandler(handler: GestureHandler<*>, sourceEvent: MotionEvent) { if (!isViewAttachedUnderWrapper(handler.view)) { handler.cancel() return @@ -250,18 +250,9 @@ class GestureHandlerOrchestrator( if (!handler.wantEvents()) { return } - val action = event.actionMasked - val coords = tempCoords - extractCoordsForView(handler.view, event, coords) - val oldX = event.x - val oldY = event.y - // TODO: we may consider scaling events if necessary using MotionEvent.transform - // for now the events are only offset to the top left corner of the view but if - // view or any ot the parents is scaled the other pointers position will not reflect - // their actual place in the view. On the other hand not scaling seems like a better - // approach when we want to use pointer coordinates to calculate velocity or distance - // for pinch so I don't know yet if we should transform or not... - event.setLocation(coords[0], coords[1]) + + val action = sourceEvent.actionMasked + val event = transformEventToViewCoords(handler.view, MotionEvent.obtain(sourceEvent)) // Touch events are sent before the handler itself has a chance to process them, // mainly because `onTouchesUp` shoul be send befor gesture finishes. This means that @@ -277,7 +268,7 @@ class GestureHandlerOrchestrator( if (!handler.isAwaiting || action != MotionEvent.ACTION_MOVE) { val isFirstEvent = handler.state == 0 - handler.handle(event) + handler.handle(event, sourceEvent) if (handler.isActive) { // After handler is done waiting for other one to fail its progress should be // reset, otherwise there may be a visible jump in values sent by the handler. @@ -305,7 +296,7 @@ class GestureHandlerOrchestrator( } } - event.setLocation(oldX, oldY) + event.recycle() } /** @@ -329,19 +320,75 @@ class GestureHandlerOrchestrator( return parent === wrapperView } - private fun extractCoordsForView(view: View?, event: MotionEvent, outputCoords: FloatArray) { - if (view === wrapperView) { - outputCoords[0] = event.x - outputCoords[1] = event.y - return + /** + * Transforms an event in the coordinates of wrapperView into the coordinate space of the received view. + * + * This modifies and returns the same event as it receives + * + * @param view - view to which coordinate space the event should be transformed + * @param event - event to transform + */ + fun transformEventToViewCoords(view: View?, event: MotionEvent): MotionEvent { + if (view == null) { + return event } - require(!(view == null || view.parent !is ViewGroup)) { "Parent is null? View is no longer in the tree" } - val parent = view.parent as ViewGroup - extractCoordsForView(parent, event, outputCoords) - val childPoint = tempPoint - transformTouchPointToViewCoords(outputCoords[0], outputCoords[1], parent, view, childPoint) - outputCoords[0] = childPoint.x - outputCoords[1] = childPoint.y + + val parent = view.parent as? ViewGroup + // Events are passed down to the orchestrator by the wrapperView, so they are already in the + // relevant coordinate space. We want to stop traversing the tree when we reach it. + if (parent != wrapperView) { + transformEventToViewCoords(parent, event) + } + + if (parent != null) { + val localX = event.x + parent.scrollX - view.left + val localY = event.y + parent.scrollY - view.top + event.setLocation(localX, localY) + } + + if (!view.matrix.isIdentity) { + view.matrix.invert(inverseMatrix) + event.transform(inverseMatrix) + } + + return event + } + + /** + * Transforms a point in the coordinates of wrapperView into the coordinate space of the received view. + * + * This modifies and returns the same point as it receives + * + * @param view - view to which coordinate space the point should be transformed + * @param point - point to transform + */ + fun transformPointToViewCoords(view: View?, point: PointF): PointF { + if (view == null) { + return point + } + + val parent = view.parent as? ViewGroup + // Events are passed down to the orchestrator by the wrapperView, so they are already in the + // relevant coordinate space. We want to stop traversing the tree when we reach it. + if (parent != wrapperView) { + transformPointToViewCoords(parent, point) + } + + if (parent != null) { + point.x += parent.scrollX - view.left + point.y += parent.scrollY - view.top + } + + if (!view.matrix.isIdentity) { + view.matrix.invert(inverseMatrix) + tempCoords[0] = point.x + tempCoords[1] = point.y + inverseMatrix.mapPoints(tempCoords) + point.x = tempCoords[0] + point.y = tempCoords[1] + } + + return point } private fun addAwaitingHandler(handler: GestureHandler<*>) { @@ -451,7 +498,7 @@ class GestureHandlerOrchestrator( val child = viewConfigHelper.getChildInDrawingOrderAtIndex(viewGroup, i) if (canReceiveEvents(child)) { val childPoint = tempPoint - transformTouchPointToViewCoords(coords[0], coords[1], viewGroup, child, childPoint) + transformPointToChildViewCoords(coords[0], coords[1], viewGroup, child, childPoint) val restoreX = coords[0] val restoreY = coords[1] coords[0] = childPoint.x @@ -564,7 +611,7 @@ class GestureHandlerOrchestrator( return isLeafOrTransparent && isTransformedTouchPointInView(coords[0], coords[1], view) } - private fun transformTouchPointToViewCoords( + private fun transformPointToChildViewCoords( x: Float, y: Float, parent: ViewGroup, diff --git a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/GestureUtils.kt b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/GestureUtils.kt index def114cba35b2..b7198c9e8087a 100644 --- a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/GestureUtils.kt +++ b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/GestureUtils.kt @@ -4,14 +4,13 @@ import android.view.MotionEvent object GestureUtils { fun getLastPointerX(event: MotionEvent, averageTouches: Boolean): Float { - val offset = event.rawX - event.x val excludeIndex = if (event.actionMasked == MotionEvent.ACTION_POINTER_UP) event.actionIndex else -1 return if (averageTouches) { var sum = 0f var count = 0 for (i in 0 until event.pointerCount) { if (i != excludeIndex) { - sum += event.getX(i) + offset + sum += event.getX(i) count++ } } @@ -21,19 +20,18 @@ object GestureUtils { if (lastPointerIdx == excludeIndex) { lastPointerIdx-- } - event.getX(lastPointerIdx) + offset + event.getX(lastPointerIdx) } } fun getLastPointerY(event: MotionEvent, averageTouches: Boolean): Float { - val offset = event.rawY - event.y val excludeIndex = if (event.actionMasked == MotionEvent.ACTION_POINTER_UP) event.actionIndex else -1 return if (averageTouches) { var sum = 0f var count = 0 for (i in 0 until event.pointerCount) { if (i != excludeIndex) { - sum += event.getY(i) + offset + sum += event.getY(i) count++ } } @@ -43,7 +41,7 @@ object GestureUtils { if (lastPointerIdx == excludeIndex) { lastPointerIdx -= 1 } - event.getY(lastPointerIdx) + offset + event.getY(lastPointerIdx) } } } diff --git a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/LongPressGestureHandler.kt b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/LongPressGestureHandler.kt index 6f67d90a613a5..fe975593fa472 100644 --- a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/LongPressGestureHandler.kt +++ b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/LongPressGestureHandler.kt @@ -37,13 +37,13 @@ class LongPressGestureHandler(context: Context) : GestureHandler 0) { handler!!.postDelayed({ activate() }, minDurationMs) @@ -51,7 +51,7 @@ class LongPressGestureHandler(context: Context) : GestureHandler maxDistSq) { if (state == STATE_ACTIVE) { diff --git a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/ManualGestureHandler.kt b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/ManualGestureHandler.kt index 11e713da5db22..9d3a3f571f0a0 100644 --- a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/ManualGestureHandler.kt +++ b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/ManualGestureHandler.kt @@ -3,7 +3,7 @@ package versioned.host.exp.exponent.modules.api.components.gesturehandler import android.view.MotionEvent class ManualGestureHandler : GestureHandler() { - override fun onHandle(event: MotionEvent) { + override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) { if (state == STATE_UNDETERMINED) { begin() } diff --git a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/NativeViewGestureHandler.kt b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/NativeViewGestureHandler.kt index b062f06f08a73..5cc1c0bf47eef 100644 --- a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/NativeViewGestureHandler.kt +++ b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/NativeViewGestureHandler.kt @@ -75,7 +75,7 @@ class NativeViewGestureHandler : GestureHandler() { } } - override fun onHandle(event: MotionEvent) { + override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) { val view = view!! if (event.actionMasked == MotionEvent.ACTION_UP) { view.onTouchEvent(event) diff --git a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/PanGestureHandler.kt b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/PanGestureHandler.kt index f96a91a341d44..84663192b50f4 100644 --- a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/PanGestureHandler.kt +++ b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/PanGestureHandler.kt @@ -205,31 +205,31 @@ class PanGestureHandler(context: Context?) : GestureHandler() return failOffsetYEnd != MIN_VALUE_IGNORE && dy > failOffsetYEnd } - override fun onHandle(event: MotionEvent) { + override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) { val state = state - val action = event.actionMasked + val action = sourceEvent.actionMasked if (action == MotionEvent.ACTION_POINTER_UP || action == MotionEvent.ACTION_POINTER_DOWN) { // update offset if new pointer gets added or removed offsetX += lastX - startX offsetY += lastY - startY // reset starting point - lastX = getLastPointerX(event, averageTouches) - lastY = getLastPointerY(event, averageTouches) + lastX = getLastPointerX(sourceEvent, averageTouches) + lastY = getLastPointerY(sourceEvent, averageTouches) startX = lastX startY = lastY } else { - lastX = getLastPointerX(event, averageTouches) - lastY = getLastPointerY(event, averageTouches) + lastX = getLastPointerX(sourceEvent, averageTouches) + lastY = getLastPointerY(sourceEvent, averageTouches) } - if (state == STATE_UNDETERMINED && event.pointerCount >= minPointers) { + if (state == STATE_UNDETERMINED && sourceEvent.pointerCount >= minPointers) { resetProgress() offsetX = 0f offsetY = 0f velocityX = 0f velocityY = 0f velocityTracker = VelocityTracker.obtain() - addVelocityMovement(velocityTracker, event) + addVelocityMovement(velocityTracker, sourceEvent) begin() if (activateAfterLongPress > 0) { @@ -239,7 +239,7 @@ class PanGestureHandler(context: Context?) : GestureHandler() handler!!.postDelayed(activateDelayed, activateAfterLongPress) } } else if (velocityTracker != null) { - addVelocityMovement(velocityTracker, event) + addVelocityMovement(velocityTracker, sourceEvent) velocityTracker!!.computeCurrentVelocity(1000) velocityX = velocityTracker!!.xVelocity velocityY = velocityTracker!!.yVelocity @@ -250,14 +250,14 @@ class PanGestureHandler(context: Context?) : GestureHandler() } else { fail() } - } else if (action == MotionEvent.ACTION_POINTER_DOWN && event.pointerCount > maxPointers) { + } else if (action == MotionEvent.ACTION_POINTER_DOWN && sourceEvent.pointerCount > maxPointers) { // When new finger is placed down (POINTER_DOWN) we check if MAX_POINTERS is not exceeded if (state == STATE_ACTIVE) { cancel() } else { fail() } - } else if (action == MotionEvent.ACTION_POINTER_UP && state == STATE_ACTIVE && event.pointerCount < minPointers) { + } else if (action == MotionEvent.ACTION_POINTER_UP && state == STATE_ACTIVE && sourceEvent.pointerCount < minPointers) { // When finger is lifted up (POINTER_UP) and the number of pointers falls below MIN_POINTERS // threshold, we only want to take an action when the handler has already activated. Otherwise // we can still expect more fingers to be placed on screen and fulfill MIN_POINTERS criteria. diff --git a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/PinchGestureHandler.kt b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/PinchGestureHandler.kt index 56ec6acc25c05..e89904cc271e6 100644 --- a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/PinchGestureHandler.kt +++ b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/PinchGestureHandler.kt @@ -1,5 +1,6 @@ package versioned.host.exp.exponent.modules.api.components.gesturehandler +import android.graphics.PointF import android.view.MotionEvent import android.view.ViewConfiguration import kotlin.math.abs @@ -9,10 +10,10 @@ class PinchGestureHandler : GestureHandler() { private set var velocity = 0.0 private set - val focalPointX: Float - get() = scaleGestureDetector?.focusX ?: Float.NaN - val focalPointY: Float - get() = scaleGestureDetector?.focusY ?: Float.NaN + var focalPointX: Float = Float.NaN + private set + var focalPointY: Float = Float.NaN + private set private var scaleGestureDetector: ScaleGestureDetector? = null private var startingSpan = 0f @@ -47,7 +48,7 @@ class PinchGestureHandler : GestureHandler() { } } - override fun onHandle(event: MotionEvent) { + override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) { if (state == STATE_UNDETERMINED) { val context = view!!.context resetProgress() @@ -56,14 +57,19 @@ class PinchGestureHandler : GestureHandler() { spanSlop = configuration.scaledTouchSlop.toFloat() begin() } - scaleGestureDetector?.onTouchEvent(event) - var activePointers = event.pointerCount - if (event.actionMasked == MotionEvent.ACTION_POINTER_UP) { + scaleGestureDetector?.onTouchEvent(sourceEvent) + scaleGestureDetector?.let { + val point = transformPoint(PointF(it.focusX, it.focusY)) + this.focalPointX = point.x + this.focalPointY = point.y + } + var activePointers = sourceEvent.pointerCount + if (sourceEvent.actionMasked == MotionEvent.ACTION_POINTER_UP) { activePointers -= 1 } if (state == STATE_ACTIVE && activePointers < 2) { end() - } else if (event.actionMasked == MotionEvent.ACTION_UP) { + } else if (sourceEvent.actionMasked == MotionEvent.ACTION_UP) { fail() } } @@ -78,6 +84,8 @@ class PinchGestureHandler : GestureHandler() { override fun onReset() { scaleGestureDetector = null + focalPointX = Float.NaN + focalPointY = Float.NaN resetProgress() } diff --git a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/RotationGestureHandler.kt b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/RotationGestureHandler.kt index be9ff4b61e942..a8e120704619d 100644 --- a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/RotationGestureHandler.kt +++ b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/RotationGestureHandler.kt @@ -1,5 +1,6 @@ package versioned.host.exp.exponent.modules.api.components.gesturehandler +import android.graphics.PointF import android.view.MotionEvent import versioned.host.exp.exponent.modules.api.components.gesturehandler.RotationGestureDetector.OnRotationGestureListener import kotlin.math.abs @@ -10,11 +11,10 @@ class RotationGestureHandler : GestureHandler() { private set var velocity = 0.0 private set - - val anchorX: Float - get() = rotationGestureDetector?.anchorX ?: Float.NaN - val anchorY: Float - get() = rotationGestureDetector?.anchorY ?: Float.NaN + var anchorX: Float = Float.NaN + private set + var anchorY: Float = Float.NaN + private set init { setShouldCancelWhenOutside(false) @@ -41,14 +41,19 @@ class RotationGestureHandler : GestureHandler() { } } - override fun onHandle(event: MotionEvent) { + override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) { if (state == STATE_UNDETERMINED) { resetProgress() rotationGestureDetector = RotationGestureDetector(gestureListener) begin() } - rotationGestureDetector?.onTouchEvent(event) - if (event.actionMasked == MotionEvent.ACTION_UP) { + rotationGestureDetector?.onTouchEvent(sourceEvent) + rotationGestureDetector?.let { + val point = transformPoint(PointF(it.anchorX, it.anchorY)) + anchorX = point.x + anchorY = point.y + } + if (sourceEvent.actionMasked == MotionEvent.ACTION_UP) { if (state == STATE_ACTIVE) { end() } else { @@ -67,6 +72,8 @@ class RotationGestureHandler : GestureHandler() { override fun onReset() { rotationGestureDetector = null + anchorX = Float.NaN + anchorY = Float.NaN resetProgress() } diff --git a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/TapGestureHandler.kt b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/TapGestureHandler.kt index 0800edc4ee4aa..0242acafc9770 100644 --- a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/TapGestureHandler.kt +++ b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/TapGestureHandler.kt @@ -104,28 +104,28 @@ class TapGestureHandler : GestureHandler() { return maxDistSq != MAX_VALUE_IGNORE && dist > maxDistSq } - override fun onHandle(event: MotionEvent) { + override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) { val state = state - val action = event.actionMasked + val action = sourceEvent.actionMasked if (state == STATE_UNDETERMINED) { offsetX = 0f offsetY = 0f - startX = event.rawX - startY = event.rawY + startX = getLastPointerX(sourceEvent, true) + startY = getLastPointerY(sourceEvent, true) } if (action == MotionEvent.ACTION_POINTER_UP || action == MotionEvent.ACTION_POINTER_DOWN) { offsetX += lastX - startX offsetY += lastY - startY - lastX = getLastPointerX(event, true) - lastY = getLastPointerY(event, true) + lastX = getLastPointerX(sourceEvent, true) + lastY = getLastPointerY(sourceEvent, true) startX = lastX startY = lastY } else { - lastX = getLastPointerX(event, true) - lastY = getLastPointerY(event, true) + lastX = getLastPointerX(sourceEvent, true) + lastY = getLastPointerY(sourceEvent, true) } - if (currentMaxNumberOfPointers < event.pointerCount) { - currentMaxNumberOfPointers = event.pointerCount + if (currentMaxNumberOfPointers < sourceEvent.pointerCount) { + currentMaxNumberOfPointers = sourceEvent.pointerCount } if (shouldFail()) { fail() diff --git a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/react/RNGestureHandlerButtonViewManager.kt b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/react/RNGestureHandlerButtonViewManager.kt index 27ab12d30b861..5fdf80ba84b41 100644 --- a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/react/RNGestureHandlerButtonViewManager.kt +++ b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/react/RNGestureHandlerButtonViewManager.kt @@ -168,6 +168,10 @@ class RNGestureHandlerButtonViewManager : ViewGroupManager(), R * [versioned.host.exp.exponent.modules.api.components.gesturehandler.NativeViewGestureHandler.onHandle] */ @SuppressLint("ClickableViewAccessibility") override fun onTouchEvent(event: MotionEvent): Boolean { + if (event.action == MotionEvent.ACTION_CANCEL) { + tryFreeingResponder() + } + val eventTime = event.eventTime val action = event.action // always true when lastEventTime or lastAction have default value (-1) @@ -268,7 +272,7 @@ class RNGestureHandlerButtonViewManager : ViewGroupManager(), R } override fun drawableHotspotChanged(x: Float, y: Float) { - if (responder == null || responder === this) { + if (touchResponder == null || touchResponder === this) { super.drawableHotspotChanged(x, y) } } @@ -281,19 +285,31 @@ class RNGestureHandlerButtonViewManager : ViewGroupManager(), R return isResponder } + override fun afterGestureEnd(event: MotionEvent) { + tryFreeingResponder() + isTouched = false + } + + private fun tryFreeingResponder() { + if (touchResponder === this) { + touchResponder = null + soundResponder = this + } + } + private fun tryGrabbingResponder(): Boolean { if (isChildTouched()) { return false } - if (responder == null) { - responder = this + if (touchResponder == null) { + touchResponder = this return true } return if (exclusive) { - responder === this + touchResponder === this } else { - !(responder?.exclusive ?: false) + !(touchResponder?.exclusive ?: false) } } @@ -314,7 +330,8 @@ class RNGestureHandlerButtonViewManager : ViewGroupManager(), R override fun performClick(): Boolean { // don't preform click when a child button is pressed (mainly to prevent sound effect of // a parent button from playing) - return if (!isChildTouched()) { + return if (!isChildTouched() && soundResponder == this) { + soundResponder = null super.performClick() } else { false @@ -328,22 +345,23 @@ class RNGestureHandlerButtonViewManager : ViewGroupManager(), R // when canStart is called eventually, tryGrabbingResponder will return true if the button // already is a responder if (pressed) { - tryGrabbingResponder() + if (tryGrabbingResponder()) { + soundResponder = this + } } // button can be pressed alongside other button if both are non-exclusive and it doesn't have // any pressed children (to prevent pressing the parent when children is pressed). - val canBePressedAlongsideOther = !exclusive && responder?.exclusive != true && !isChildTouched() + val canBePressedAlongsideOther = !exclusive && touchResponder?.exclusive != true && !isChildTouched() - if (!pressed || responder === this || canBePressedAlongsideOther) { + if (!pressed || touchResponder === this || canBePressedAlongsideOther) { // we set pressed state only for current responder or any non-exclusive button when responder // is null or non-exclusive, assuming it doesn't have pressed children isTouched = pressed super.setPressed(pressed) } - if (!pressed && responder === this) { + if (!pressed && touchResponder === this) { // if the responder is no longer pressed we release button responder - responder = null isTouched = false } } @@ -355,7 +373,8 @@ class RNGestureHandlerButtonViewManager : ViewGroupManager(), R companion object { var resolveOutValue = TypedValue() - var responder: ButtonViewGroup? = null + var touchResponder: ButtonViewGroup? = null + var soundResponder: ButtonViewGroup? = null var dummyClickListener = OnClickListener { } } } diff --git a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/react/RNGestureHandlerModule.kt b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/react/RNGestureHandlerModule.kt index 890a74b4d96ea..3b10389ca544d 100644 --- a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/react/RNGestureHandlerModule.kt +++ b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/react/RNGestureHandlerModule.kt @@ -347,7 +347,7 @@ class RNGestureHandlerModule(reactContext: ReactApplicationContext?) val registry: RNGestureHandlerRegistry = RNGestureHandlerRegistry() private val interactionManager = RNGestureHandlerInteractionManager() private val roots: MutableList = ArrayList() - private val enqueuedRootViewInit: MutableList = ArrayList() + private val reanimatedEventDispatcher = ReanimatedEventDispatcher() override fun getName() = MODULE_NAME @ReactMethod @@ -594,7 +594,7 @@ class RNGestureHandlerModule(reactContext: ReactApplicationContext?) // Delivers the event to Reanimated. if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { // Send event directly to Reanimated - // ReanimatedEventDispatcher.sendEvent(event, reactApplicationContext) // COMMENTED OUT BY VENDORING SCRIPT + reanimatedEventDispatcher.sendEvent(event, reactApplicationContext) } else { // In the old architecture, Reanimated subscribes for specific direct events. sendEventForDirectEvent(event) diff --git a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/react/RNGestureHandlerRootHelper.kt b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/react/RNGestureHandlerRootHelper.kt index 90570d118f8dd..3db1cf07785dc 100644 --- a/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/react/RNGestureHandlerRootHelper.kt +++ b/android/expoview/src/main/java/versioned/host/exp/exponent/modules/api/components/gesturehandler/react/RNGestureHandlerRootHelper.kt @@ -54,7 +54,7 @@ class RNGestureHandlerRootHelper(private val context: ReactContext, wrappedView: } private inner class RootViewGestureHandler : GestureHandler() { - override fun onHandle(event: MotionEvent) { + override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) { val currentState = state if (currentState == STATE_UNDETERMINED) { begin() diff --git a/apps/bare-expo/package.json b/apps/bare-expo/package.json index 6aca554746fca..21f8cf920c6e5 100644 --- a/apps/bare-expo/package.json +++ b/apps/bare-expo/package.json @@ -112,7 +112,7 @@ "react": "18.1.0", "react-dom": "18.0.0", "react-native": "0.70.1", - "react-native-gesture-handler": "~2.6.2", + "react-native-gesture-handler": "~2.7.0", "react-native-reanimated": "~2.10.0", "react-native-safe-area-context": "4.3.1", "react-native-screens": "~3.15.0", diff --git a/apps/bare-sandbox/package.json b/apps/bare-sandbox/package.json index 5b9da44446fd2..df7c55245e881 100644 --- a/apps/bare-sandbox/package.json +++ b/apps/bare-sandbox/package.json @@ -18,7 +18,7 @@ "react": "18.1.0", "react-dom": "18.0.0", "react-native": "0.70.1", - "react-native-gesture-handler": "~2.6.2", + "react-native-gesture-handler": "~2.7.0", "react-native-reanimated": "~2.10.0", "react-native-screens": "~3.15.0", "react-native-web": "~0.18.9" diff --git a/apps/native-component-list/package.json b/apps/native-component-list/package.json index 3a50cce6a8a1d..422ef07495955 100644 --- a/apps/native-component-list/package.json +++ b/apps/native-component-list/package.json @@ -144,7 +144,7 @@ "react": "18.1.0", "react-dom": "18.0.0", "react-native": "0.70.1", - "react-native-gesture-handler": "~2.6.2", + "react-native-gesture-handler": "~2.7.0", "react-native-iphone-x-helper": "^1.3.0", "react-native-maps": "0.31.1", "react-native-pager-view": "5.4.24", diff --git a/apps/test-suite/package.json b/apps/test-suite/package.json index fc364daebab9a..52cfc6a6ad77a 100644 --- a/apps/test-suite/package.json +++ b/apps/test-suite/package.json @@ -51,7 +51,7 @@ "lodash": "^4.17.19", "react": "18.1.0", "react-native": "0.70.1", - "react-native-gesture-handler": "~2.6.2", + "react-native-gesture-handler": "~2.7.0", "react-native-safe-area-view": "^0.14.8", "sinon": "^7.1.1" }, diff --git a/home/package.json b/home/package.json index 1d6e5c3f79481..8d6885472675e 100644 --- a/home/package.json +++ b/home/package.json @@ -55,7 +55,7 @@ "react": "18.1.0", "react-native": "0.70.1", "react-native-fade-in-image": "^1.6.1", - "react-native-gesture-handler": "~2.6.2", + "react-native-gesture-handler": "~2.7.0", "react-native-infinite-scroll-view": "^0.4.5", "react-native-keyboard-aware-scroll-view": "^0.9.5", "react-native-maps": "0.31.1", diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 4bd14020991c6..8fd8d44322863 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -2014,7 +2014,7 @@ PODS: - React-perflogger (= 0.70.1) - RNFlashList (1.3.0): - React-Core - - RNGestureHandler (2.6.2): + - RNGestureHandler (2.7.0): - React-Core - RNReanimated (2.9.1): - DoubleConversion @@ -3509,7 +3509,7 @@ SPEC CHECKSUMS: React-runtimeexecutor: a11d0c2e14140baf1e449264ca9168ae9ae6bbd0 ReactCommon: 7f86326b92009925c6dcf93f8e825060171c379f RNFlashList: 5116f2de2f543f01bfc30b22d5942d5af84b43df - RNGestureHandler: 4defbd70b2faf3d6761b82fa7880285241762cb0 + RNGestureHandler: 7673697e7c0e9391adefae4faa087442bc04af33 RNReanimated: 5c8c17e26787fd8984cd5accdc70fef2ca70aafd RNScreens: 4a1af06327774490d97342c00aee0c2bafb497b7 Stripe: fb29a476e4866fec4ef22fb76207363dd32795aa diff --git a/ios/vendored/unversioned/react-native-gesture-handler/RNGestureHandler.podspec.json b/ios/vendored/unversioned/react-native-gesture-handler/RNGestureHandler.podspec.json index 80578f05ad105..86e5b94d10d18 100644 --- a/ios/vendored/unversioned/react-native-gesture-handler/RNGestureHandler.podspec.json +++ b/ios/vendored/unversioned/react-native-gesture-handler/RNGestureHandler.podspec.json @@ -1,6 +1,6 @@ { "name": "RNGestureHandler", - "version": "2.6.2", + "version": "2.7.0", "summary": "Experimental implementation of a new declarative API for gesture handling in react-native", "homepage": "https://github.com/software-mansion/react-native-gesture-handler", "license": "MIT", @@ -9,7 +9,7 @@ }, "source": { "git": "https://github.com/software-mansion/react-native-gesture-handler", - "tag": "2.6.2" + "tag": "2.7.0" }, "source_files": "ios/**/*.{h,m,mm}", "requires_arc": true, diff --git a/ios/vendored/unversioned/react-native-gesture-handler/ios/RNGestureHandlerButtonComponentView.mm b/ios/vendored/unversioned/react-native-gesture-handler/ios/RNGestureHandlerButtonComponentView.mm index 29ac1566b1282..0688a780495db 100644 --- a/ios/vendored/unversioned/react-native-gesture-handler/ios/RNGestureHandlerButtonComponentView.mm +++ b/ios/vendored/unversioned/react-native-gesture-handler/ios/RNGestureHandlerButtonComponentView.mm @@ -5,10 +5,10 @@ #import #import -#import -#import -#import -#import +#import +#import +#import +#import #import "RNGestureHandlerButton.h" diff --git a/packages/expo-stories/package.json b/packages/expo-stories/package.json index f51f60db638ec..7796b72d5a03b 100644 --- a/packages/expo-stories/package.json +++ b/packages/expo-stories/package.json @@ -30,7 +30,7 @@ "esbuild": "^0.12.15", "fs-extra": "^9.1.0", "glob": "^7.1.7", - "react-native-gesture-handler": "~2.6.2", + "react-native-gesture-handler": "~2.7.0", "react-native-safe-area-context": "4.3.1", "react-native-screens": "~3.15.0", "react-native-svg": "12.3.0", diff --git a/packages/expo/bundledNativeModules.json b/packages/expo/bundledNativeModules.json index 91033690a38a8..de19d446731ac 100644 --- a/packages/expo/bundledNativeModules.json +++ b/packages/expo/bundledNativeModules.json @@ -90,7 +90,7 @@ "react-native": "0.70.1", "react-native-web": "~0.18.9", "react-native-branch": "^5.4.0", - "react-native-gesture-handler": "~2.6.2", + "react-native-gesture-handler": "~2.7.0", "react-native-get-random-values": "~1.8.0", "react-native-maps": "0.31.1", "react-native-pager-view": "5.4.24",