-
Notifications
You must be signed in to change notification settings - Fork 6k
[ios][platform_view] Fix Platform view gesture recognizer with iPad pencil getting stuck #55724
[ios][platform_view] Fix Platform view gesture recognizer with iPad pencil getting stuck #55724
Conversation
@@ -654,14 +654,14 @@ - (instancetype)initWithTarget:(id)target | |||
|
|||
- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer | |||
shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer { | |||
// The forwarding gesture recognizer should always get all touch events, so it should not be | |||
// required to fail by any other gesture recognizer. | |||
return otherGestureRecognizer != _forwardingRecognizer && otherGestureRecognizer != self; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we set self as the delegate, otherGestureRecognizer != self
is always YES.
I can confirm this fixed the issue, but need to make sure it doesn't break anything |
Logic introduced in #6665 |
Running the presubmit test now. I also manually tested a few scenario:
Also iPad pencil doesn't break the gestures in above examples. |
Tested the webview package's example app -
|
Tested on google map package's example app (this app is pretty well made and it covers lots of gesture functionalities, so it gives me lots of confidence). I tried all the following features related to touch/gesture:
|
Tried web view example again with the main branch - confirmed same behavior as expected. |
Tried google map example again with the main branch - also same behavior as expected. |
Verified the regression in previous workaround (UIButton's callback not being called) doesn't happen in this PR. |
66eb926
to
7381f37
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have gesture integration tests? Can we add something to scenario app to test some of the manual tests you did?
For this particular bug: I don't think it's possible to mimic ipad pencil interaction in XCUITests. I couldn't find any suitable API (e.g. XCUIElement APIs). The manual tests I did was to ensure we don't regress our general gesture logic (unfortunately they won't help catch this bug). We don't have any of those tests, but I think we should add those to improve our code quality. That would be a pretty big project though, so I'm leaning towards having it as a separate project. I can create a ticket maybe for next year. WDYT? @jmagman I don't think Scenario test will do - we need the framework part as well (e.g. to check if |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The manual tests I did was to ensure we don't regress our general gesture logic (unfortunately they won't help catch this bug). We don't have any of those tests, but I think we should add those to improve our code quality. That would be a pretty big project though, so I'm leaning towards having it as a separate project. I can create a ticket maybe for next year. WDYT?
That would be really helpful, thank you!
LGTM let's try it.
…ith iPad pencil getting stuck (flutter/engine#55724)
…156562) flutter/engine@3f0e2fb...e41a762 2024-10-11 41930132+hellohuanlin@users.noreply.github.com [ios][platform_view] Fix Platform view gesture recognizer with iPad pencil getting stuck (flutter/engine#55724) 2024-10-11 flar@google.com [DisplayList] Create DlFoo type variants to start moving away from Skia types in API (flutter/engine#55812) 2024-10-10 jonahwilliams@google.com [engine] remove merge thread setting and fix default value. (flutter/engine#55810) 2024-10-10 skia-flutter-autoroll@skia.org Roll Skia from 1e269594df9d to 97cebfb06139 (3 revisions) (flutter/engine#55811) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC jacksongardner@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…isions) (#156562)" (#156594) Reverts: #156562 Initiated by: zanderso Reason for reverting: Linux_mokey flutter_gallery__back_button_memory is failing repeatedly on framework CI Original PR Author: engine-flutter-autoroll Reviewed By: {fluttergithubbot} This change reverts the following previous change: flutter/engine@3f0e2fb...e41a762 2024-10-11 41930132+hellohuanlin@users.noreply.github.com [ios][platform_view] Fix Platform view gesture recognizer with iPad pencil getting stuck (flutter/engine#55724) 2024-10-11 flar@google.com [DisplayList] Create DlFoo type variants to start moving away from Skia types in API (flutter/engine#55812) 2024-10-10 jonahwilliams@google.com [engine] remove merge thread setting and fix default value. (flutter/engine#55810) 2024-10-10 skia-flutter-autoroll@skia.org Roll Skia from 1e269594df9d to 97cebfb06139 (3 revisions) (flutter/engine#55811) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC jacksongardner@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…4a (4 revisions) (#156562)" (#156594)" (#156597) Reverts: #156594 Initiated by: jonahwilliams Reason for reverting: workaround landed? Original PR Author: auto-submit[bot] Reviewed By: {fluttergithubbot} This change reverts the following previous change: Reverts: #156562 Initiated by: zanderso Reason for reverting: Linux_mokey flutter_gallery__back_button_memory is failing repeatedly on framework CI Original PR Author: engine-flutter-autoroll Reviewed By: {fluttergithubbot} This change reverts the following previous change: flutter/engine@3f0e2fb...e41a762 2024-10-11 41930132+hellohuanlin@users.noreply.github.com [ios][platform_view] Fix Platform view gesture recognizer with iPad pencil getting stuck (flutter/engine#55724) 2024-10-11 flar@google.com [DisplayList] Create DlFoo type variants to start moving away from Skia types in API (flutter/engine#55812) 2024-10-10 jonahwilliams@google.com [engine] remove merge thread setting and fix default value. (flutter/engine#55810) 2024-10-10 skia-flutter-autoroll@skia.org Roll Skia from 1e269594df9d to 97cebfb06139 (3 revisions) (flutter/engine#55811) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC jacksongardner@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Time to revert pull request flutter/engine/55724 has elapsed. |
…h iPad pencil getting stuck (flutter#55724)" This reverts commit e41a762.
#55889) �h iPad pencil getting stuck (#55724)" This reverts commit e41a762. Revert since a customer reported the platform view touch is broken after the change. *List which issues are fixed by this PR. You must list at least one issue.* Reopens #55724 *If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].* [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
…encil getting stuck (flutter/engine#55724) ## Summary I came across our the "gesture recognizer delegate" implementation and it is quite odd (see below). After fixing it, the problem is resolved. However, it's hard to reason about how it's related to iPad pencil, since it's internal logic that we don't know (see my research below). ## Gesture recognizer delegate ### Existing odd implementation - shouldBeRequiredToFailByGestureRecognizer: `otherGestureRecognizer != self` is always YES because the delegate set to self, hence `gestureRecognizer` must be self, hence `otherGestureRecognizer` must not be self. - shouldRequireFailureOfGestureRecognizer: `otherGestureRecognizer == self` is always NO, for the same reason described above. ### new implementation: After digging into various PRs, the idea seems to be that we want to have a precedence of "Forwarding recognizer > Delaying recognizer > Other recognizers in platform view". - shouldBeRequiredToFailByGestureRecognizer: `return otherGestureRecognizer != _forwardingRecognizer` means Delaying recognizer needs to be higher precedence than all non-Forwarding recognizer. (aka "Delaying recognizer > Other recognizers in platform view") - shouldRequireFailureOfGestureRecognizer: `return otherGestureRecognizer == _forwardingRecognizer` means Delaying recognizer needs to have lower precedence than forwarding recognizer. (aka "Forwarding recognizer > Delaying recognizer"). ## Some research This is a tricky one since pencil and finger triggers exactly the same callbacks. It turns out that when pencil is involved after finger interaction, the platform view's "forwarding" gesture recognizer is stuck at failed state. This seems to be an iOS bug, because according to [the API doc](https://developer.apple.com/documentation/uikit/uigesturerecognizerstate/uigesturerecognizerstatefailed?language=objc), it should be reset back to "possible" state: > No action message is sent and the gesture recognizer is reset to [UIGestureRecognizerStatePossible](https://developer.apple.com/documentation/uikit/uigesturerecognizerstate/uigesturerecognizerstatepossible?language=objc). However, when iPad pencil is involved, the state is not reset. I tried to KVO the state property, and wasn't able to capture the change. This means the state change very likely happened internally within the recognizer via the backing ivar of the state property. *List which issues are fixed by this PR. You must list at least one issue.* Fixes flutter#136244 *If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].* [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
flutter/engine#55889) �h iPad pencil getting stuck (flutter#55724)" This reverts commit 21eb449. Revert since a customer reported the platform view touch is broken after the change. *List which issues are fixed by this PR. You must list at least one issue.* Reopens flutter/engine#55724 *If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].* [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
Summary
I came across our the "gesture recognizer delegate" implementation and it is quite odd (see below). After fixing it, the problem is resolved. However, it's hard to reason about how it's related to iPad pencil, since it's internal logic that we don't know (see my research below).
Gesture recognizer delegate
Existing odd implementation
otherGestureRecognizer != self
is always YES because the delegate set to self, hencegestureRecognizer
must be self, henceotherGestureRecognizer
must not be self.otherGestureRecognizer == self
is always NO, for the same reason described above.new implementation:
After digging into various PRs, the idea seems to be that we want to have a precedence of "Forwarding recognizer > Delaying recognizer > Other recognizers in platform view".
return otherGestureRecognizer != _forwardingRecognizer
means Delaying recognizer needs to be higher precedence than all non-Forwarding recognizer. (aka "Delaying recognizer > Other recognizers in platform view")return otherGestureRecognizer == _forwardingRecognizer
means Delaying recognizer needs to have lower precedence than forwarding recognizer. (aka "Forwarding recognizer > Delaying recognizer").Some research
This is a tricky one since pencil and finger triggers exactly the same callbacks. It turns out that when pencil is involved after finger interaction, the platform view's "forwarding" gesture recognizer is stuck at failed state. This seems to be an iOS bug, because according to the API doc, it should be reset back to "possible" state:
However, when iPad pencil is involved, the state is not reset. I tried to KVO the state property, and wasn't able to capture the change. This means the state change very likely happened internally within the recognizer via the backing ivar of the state property.
List which issues are fixed by this PR. You must list at least one issue.
Fixes flutter/flutter#136244
If you had to change anything in the flutter/tests repo, include a link to the migration guide as per the breaking change policy.
Pre-launch Checklist
///
).If you need help, consider asking for advice on the #hackers-new channel on Discord.