-
Notifications
You must be signed in to change notification settings - Fork 6k
PlatformViewsController always make sure the touch events are finished #22406
Conversation
| if (!_flutterViewController) { | ||
| return; | ||
| } |
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.
nit: I think these aren't necessary, since sending a message to nil is a noop.
| } | ||
| } | ||
| [_flutterViewController touchesBegan:touches withEvent:event]; | ||
| _currentTouchPointersCount += touches.count; |
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.
What's the implication of not incrementing this counter if we have no VC?
Should we be setting to zero in the early return above?
shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm
Outdated
Show resolved
Hide resolved
cyanglaz
left a comment
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.
@dnfield @gaaclarke Updated per your comments. PTAL
|
|
||
| - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { | ||
| [_platformViewsController->getFlutterViewController() touchesBegan:touches withEvent:event]; | ||
| _flutterViewController = _platformViewsController->getFlutterViewController(); |
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.
Is it possible that _platformViewsController->getFlutterViewController() could return different values between calls touchesBegan before touchesEnded has happened?
- touch-1 began
- flutter view controller changed
- touch-2 began
- touch-1 ended
- touch-2 ended
If so you'd have to be super vigilant and track the FlutterViewController at touchesBegan for each event.
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.
Has this been addressed in the recent commit(s)?
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.
Updated the code to support this scenario. I also added a test for this.
| 0D6AB6C922BB05E200EEE540 /* IosUnitTestsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IosUnitTestsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; | ||
| 0D6AB6CF22BB05E200EEE540 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; | ||
| 0D6AB73E22BD8F0200EEE540 /* FlutterEngineConfig.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = FlutterEngineConfig.xcconfig; sourceTree = "<group>"; }; | ||
| 68FF0A70255A3B4E00165B60 /* FlutterPlatformViewsTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FlutterPlatformViewsTest.mm; sourceTree = "<group>"; }; |
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.
I found that this test file is not referenced by the project, so while I'm here, I added it to the project so it helps the debugging process easier.
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.
It isn't suppose to be in here. That is linked in as part of ios_test_flutter_mrc
engine/shell/platform/darwin/ios/BUILD.gn
Line 180 in 5d4d06e
| "framework/Source/FlutterPlatformViewsTest.mm", |
You'll get duplicate symbols if you do this.
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.
You still need to remove this.
| if (_currentTouchPointersCount == 0) { | ||
| // At the start of each gesture sequence, we reset the `_flutterViewController`, | ||
| // so that all the touch events in the same sequence are forwarded to the same `_flutterViewController`. | ||
| _flutterViewController = _platformViewsController->getFlutterViewController(); | ||
| } | ||
| [_flutterViewController touchesBegan:touches withEvent:event]; |
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.
This still makes me a bit nervous. Particularly the fact that _flutterViewController is a weak reference and we are sending messages to it potentially after _platformViewsController has gotten rid of it. My suggestion was to keep a map between events and FlutterViewControllers.
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
_flutterViewControllers[event] = _platformViewsController->getFlutterViewController();
[_flutterViewControllers[event] touchesBegan:touches withEvent:event];
}
-(void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
[_flutterViewControllers[event] touchesEnded:touches withEvent:event];
[_flutterViewControllers removeObject:event];
}This has the added benefit of having a retain on the flutter view controller while it is being interacted with and everyone gets the correct message. You'll have to verify that the same event is getting passed across all of the calls.
| [_flutterViewController.get() touchesCancelled:touches withEvent:event]; | ||
| _currentTouchPointersCount -= touches.count; | ||
| if (_currentTouchPointersCount == 0) { | ||
| self.state = UIGestureRecognizerStateFailed; | ||
| _flutterViewController.reset(nil); | ||
| } |
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.
In the case where we get Begin-Begin-Cancel-End the state will no longer be Failed like it was previously, is that expected?
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.
Begin-Begin-Cancel-End makes the count to 0 at the last End, so it state would still be failed.
I don't think Begin-Begin-Cancel-End would be possible anyway, if a Cancel happens during a sequence, it cancels all the touches had begun.
| if (_currentTouchPointersCount < 0) { | ||
| // _currentTouchPointersCount should never be less than 0. | ||
| // To not breaking production code, we reset the count to 0 if a negative value | ||
| // is reached. | ||
| _currentTouchPointersCount = 0; | ||
| } |
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.
This shouldn't be possible now that you've changed the cancel logic, right?
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.
Right, removed
gaaclarke
left a comment
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.
LGTM once the PlatformViewsTest is removed from the project. There are still some things I'm not clear about but comparing this code to what was before it, this is an improvement and a fix. Thanks chris.
| 0D6AB6C922BB05E200EEE540 /* IosUnitTestsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IosUnitTestsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; | ||
| 0D6AB6CF22BB05E200EEE540 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; | ||
| 0D6AB73E22BD8F0200EEE540 /* FlutterEngineConfig.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = FlutterEngineConfig.xcconfig; sourceTree = "<group>"; }; | ||
| 68FF0A70255A3B4E00165B60 /* FlutterPlatformViewsTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FlutterPlatformViewsTest.mm; sourceTree = "<group>"; }; |
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.
You still need to remove this.
|
@gaaclarke Removed the reference. @dnfield PTAL |
Description
Regression: After #20708, touch events might not able to finish if FlutterViewController is unset in the middle of the touch events. This PR asks the ForwardGestureRecognizer to hold a reference to the FlutterViewController at least until the end of the touch events.
Related Issues
Fixes flutter/flutter#66097
Tests
testSetFlutterViewControllerToNilInTheMiddleOfTouchEventShouldStillAllowGesturesToBeHandled
Checklist
Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes (
[x]). This will ensure a smooth and quick review process.Reviewer Checklist
Breaking Change
Did any tests fail when you ran them? Please read handling breaking changes.