Skip to content

Commit

Permalink
Make sure FlutterViewController flushs all pending touches when no lo…
Browse files Browse the repository at this point in the history
…nger active (flutter#8400)
  • Loading branch information
xster authored Apr 4, 2019
1 parent 06cab81 commit 8b74cba
Showing 1 changed file with 59 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ @implementation FlutterViewController {
BOOL _initialized;
BOOL _viewOpaque;
BOOL _engineNeedsLaunch;
NSMutableSet<NSNumber*>* _ongoingTouches;
}

#pragma mark - Manage and override all designated initializers
Expand All @@ -54,6 +55,7 @@ - (instancetype)initWithEngine:(FlutterEngine*)engine
_engineNeedsLaunch = NO;
_flutterView.reset([[FlutterView alloc] initWithDelegate:_engine opaque:self.isViewOpaque]);
_weakFactory = std::make_unique<fml::WeakPtrFactory<FlutterViewController>>(self);
_ongoingTouches = [[NSMutableSet alloc] init];

[self performCommonViewControllerInitialization];
[engine setViewController:self];
Expand All @@ -75,6 +77,7 @@ - (instancetype)initWithProject:(FlutterDartProject*)projectOrNil
_flutterView.reset([[FlutterView alloc] initWithDelegate:_engine opaque:self.isViewOpaque]);
[_engine.get() createShell:nil libraryURI:nil];
_engineNeedsLaunch = YES;
_ongoingTouches = [[NSMutableSet alloc] init];
[self loadDefaultSplashScreenView];
[self performCommonViewControllerInitialization];
}
Expand Down Expand Up @@ -427,9 +430,44 @@ - (void)viewDidDisappear:(BOOL)animated {
TRACE_EVENT0("flutter", "viewDidDisappear");
[self surfaceUpdated:NO];
[[_engine.get() lifecycleChannel] sendMessage:@"AppLifecycleState.paused"];
[self flushOngoingTouches];

[super viewDidDisappear:animated];
}

- (void)flushOngoingTouches {
if (_ongoingTouches.count > 0) {
auto packet = std::make_unique<blink::PointerDataPacket>(_ongoingTouches.count);
size_t pointer_index = 0;
// If the view controller is going away, we want to flush cancel all the ongoing
// touches to the framework so nothing gets orphaned.
for (NSNumber* device in _ongoingTouches) {
// Create fake PointerData to balance out each previously started one for the framework.
blink::PointerData pointer_data;
pointer_data.Clear();

constexpr int kMicrosecondsPerSecond = 1000 * 1000;
// Use current time.
pointer_data.time_stamp = [[NSDate date] timeIntervalSince1970] * kMicrosecondsPerSecond;

pointer_data.change = blink::PointerData::Change::kCancel;
pointer_data.kind = blink::PointerData::DeviceKind::kTouch;
pointer_data.device = device.longLongValue;

// Anything we put here will be arbitrary since there are no touches.
pointer_data.physical_x = 0;
pointer_data.physical_y = 0;
pointer_data.pressure = 1.0;
pointer_data.pressure_max = 1.0;

packet->SetPointerData(pointer_index++, pointer_data);
}

[_ongoingTouches removeAllObjects];
[_engine.get() dispatchPointerDataPacket:std::move(packet)];
}
}

- (void)dealloc {
[_engine.get() notifyViewControllerDeallocated];
[[NSNotificationCenter defaultCenter] removeObserver:self];
Expand Down Expand Up @@ -528,6 +566,27 @@ - (void)dispatchTouches:(NSSet*)touches
pointer_data.physical_x = windowCoordinates.x * scale;
pointer_data.physical_y = windowCoordinates.y * scale;

NSNumber* deviceKey = [NSNumber numberWithLongLong:pointer_data.device];
// Track touches that began and not yet stopped so we can flush them
// if the view controller goes away.
switch (pointer_data.change) {
case blink::PointerData::Change::kDown:
[_ongoingTouches addObject:deviceKey];
break;
case blink::PointerData::Change::kCancel:
case blink::PointerData::Change::kUp:
[_ongoingTouches removeObject:deviceKey];
break;
case blink::PointerData::Change::kHover:
case blink::PointerData::Change::kMove:
// We're only tracking starts and stops.
break;
case blink::PointerData::Change::kAdd:
case blink::PointerData::Change::kRemove:
// We don't use kAdd/kRemove.
break;
}

// pressure_min is always 0.0
if (@available(iOS 9, *)) {
// These properties were introduced in iOS 9.0.
Expand Down

0 comments on commit 8b74cba

Please sign in to comment.