Skip to content

Commit

Permalink
Prevent child gestures from activating when a parent gesture is alrea…
Browse files Browse the repository at this point in the history
…dy active (#3296)

## Description

Restores
#3095
with a small change, I guess supersedes
#3264.

## Test plan

Same as in
#3095

See also
#3264 (comment)
  • Loading branch information
j-piasecki authored Dec 18, 2024
1 parent 41defa7 commit 9dabf26
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,22 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
}
}

/*
* Returns true if the view this handler is attached to is a descendant of the view the other handler
* is attached to and false otherwise.
*/
fun isDescendantOf(of: GestureHandler<*>): Boolean {
var view = this.view?.parent as? View
while (view != null) {
if (view == of.view) {
return true
}

view = view.parent as? View
}
return false
}

// responsible for resetting the state of handler upon activation (may be called more than once
// if the handler is waiting for failure of other one)
open fun resetProgress() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,15 @@ class GestureHandlerOrchestrator(
private fun hasOtherHandlerToWaitFor(handler: GestureHandler<*>) =
gestureHandlers.any { !isFinished(it.state) && shouldHandlerWaitForOther(handler, it) }

private fun shouldBeCancelledByFinishedHandler(handler: GestureHandler<*>) = gestureHandlers.any { shouldHandlerWaitForOther(handler, it) && it.state == GestureHandler.STATE_END }
private fun shouldBeCancelledByFinishedHandler(handler: GestureHandler<*>) =
gestureHandlers.any { shouldHandlerWaitForOther(handler, it) && it.state == GestureHandler.STATE_END }

private fun shouldBeCancelledByActiveHandler(handler: GestureHandler<*>) =
gestureHandlers.any { handler.hasCommonPointers(it) && it.state == GestureHandler.STATE_ACTIVE && !canRunSimultaneously(handler, it) && handler.isDescendantOf(it) }

private fun tryActivate(handler: GestureHandler<*>) {
// If we are waiting for a gesture that has successfully finished, we should cancel handler
if (shouldBeCancelledByFinishedHandler(handler)) {
if (shouldBeCancelledByFinishedHandler(handler) || shouldBeCancelledByActiveHandler(handler)) {
handler.cancel()
return
}
Expand Down

0 comments on commit 9dabf26

Please sign in to comment.