fix a PlatformView gesture bug (#84257)
This commit is contained in:
@@ -540,20 +540,24 @@ class _AndroidMotionEventConverter {
|
||||
);
|
||||
}
|
||||
|
||||
void handlePointerUpEvent(PointerUpEvent event) {
|
||||
pointerPositions.remove(event.pointer);
|
||||
usedAndroidPointerIds.remove(pointerProperties[event.pointer]!.id);
|
||||
pointerProperties.remove(event.pointer);
|
||||
void _remove(int pointer) {
|
||||
pointerPositions.remove(pointer);
|
||||
usedAndroidPointerIds.remove(pointerProperties[pointer]!.id);
|
||||
pointerProperties.remove(pointer);
|
||||
if (pointerProperties.isEmpty) {
|
||||
downTimeMillis = null;
|
||||
}
|
||||
}
|
||||
|
||||
void handlePointerUpEvent(PointerUpEvent event) {
|
||||
_remove(event.pointer);
|
||||
}
|
||||
|
||||
void handlePointerCancelEvent(PointerCancelEvent event) {
|
||||
pointerPositions.clear();
|
||||
pointerProperties.clear();
|
||||
usedAndroidPointerIds.clear();
|
||||
downTimeMillis = null;
|
||||
// The pointer cancel event is handled like pointer up. Normally,
|
||||
// the difference is that pointer cancel doesn't perform any action,
|
||||
// but in this case neither up or cancel perform any action.
|
||||
_remove(event.pointer);
|
||||
}
|
||||
|
||||
AndroidMotionEvent? toAndroidMotionEvent(PointerEvent event) {
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
import 'package:fake_async/fake_async.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import '../services/fake_platform_views.dart';
|
||||
import 'rendering_tester.dart';
|
||||
@@ -98,6 +100,56 @@ void main() {
|
||||
});
|
||||
|
||||
}, skip: isBrowser); // TODO(yjbanov): fails on Web with obscured stack trace: https://github.com/flutter/flutter/issues/42770
|
||||
|
||||
// Regression test for https://github.com/flutter/flutter/issues/69431
|
||||
test('multi-finger touch test', () {
|
||||
renderer; // Initialize bindings.
|
||||
final FakeAndroidPlatformViewsController viewsController = FakeAndroidPlatformViewsController();
|
||||
viewsController.registerViewType('webview');
|
||||
final AndroidViewController viewController =
|
||||
PlatformViewsService.initAndroidView(id: 0, viewType: 'webview', layoutDirection: TextDirection.rtl);
|
||||
final PlatformViewRenderBox platformViewRenderBox = PlatformViewRenderBox(
|
||||
controller: viewController,
|
||||
hitTestBehavior: PlatformViewHitTestBehavior.opaque,
|
||||
gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>{
|
||||
Factory<VerticalDragGestureRecognizer>(
|
||||
() => VerticalDragGestureRecognizer(),
|
||||
),
|
||||
},
|
||||
);
|
||||
layout(platformViewRenderBox);
|
||||
pumpFrame(phase: EnginePhase.flushSemantics);
|
||||
|
||||
viewController.pointTransformer = (Offset offset) => platformViewRenderBox.globalToLocal(offset);
|
||||
|
||||
FakeAsync().run((FakeAsync async) {
|
||||
// Put one pointer down.
|
||||
ui.window.onPointerDataPacket!(ui.PointerDataPacket(data: <ui.PointerData>[
|
||||
_pointerData(ui.PointerChange.add, Offset.zero, pointer: 1, kind: PointerDeviceKind.touch),
|
||||
_pointerData(ui.PointerChange.down, const Offset(10, 10), pointer: 1, kind: PointerDeviceKind.touch),
|
||||
_pointerData(ui.PointerChange.remove, const Offset(10, 10), pointer: 1, kind: PointerDeviceKind.touch),
|
||||
]));
|
||||
async.flushMicrotasks();
|
||||
|
||||
// Put another pointer down and then cancel it.
|
||||
ui.window.onPointerDataPacket!(ui.PointerDataPacket(data: <ui.PointerData>[
|
||||
_pointerData(ui.PointerChange.add, Offset.zero, pointer: 2, kind: PointerDeviceKind.touch),
|
||||
_pointerData(ui.PointerChange.down, const Offset(20, 10), pointer: 2, kind: PointerDeviceKind.touch),
|
||||
_pointerData(ui.PointerChange.cancel, const Offset(20, 10), pointer: 2, kind: PointerDeviceKind.touch),
|
||||
]));
|
||||
async.flushMicrotasks();
|
||||
|
||||
// The first pointer can still moving without crashing.
|
||||
ui.window.onPointerDataPacket!(ui.PointerDataPacket(data: <ui.PointerData>[
|
||||
_pointerData(ui.PointerChange.add, Offset.zero, pointer: 1, kind: PointerDeviceKind.touch),
|
||||
_pointerData(ui.PointerChange.move, const Offset(10, 10), pointer: 1, kind: PointerDeviceKind.touch),
|
||||
_pointerData(ui.PointerChange.remove, const Offset(10, 10), pointer: 1, kind: PointerDeviceKind.touch),
|
||||
]));
|
||||
async.flushMicrotasks();
|
||||
});
|
||||
|
||||
// Passes if no crashes.
|
||||
});
|
||||
}
|
||||
|
||||
ui.PointerData _pointerData(
|
||||
@@ -105,8 +157,11 @@ ui.PointerData _pointerData(
|
||||
Offset logicalPosition, {
|
||||
int device = 0,
|
||||
PointerDeviceKind kind = PointerDeviceKind.mouse,
|
||||
int pointer = 0,
|
||||
}) {
|
||||
return ui.PointerData(
|
||||
pointerIdentifier: pointer,
|
||||
embedderId: pointer,
|
||||
change: change,
|
||||
physicalX: logicalPosition.dx * ui.window.devicePixelRatio,
|
||||
physicalY: logicalPosition.dy * ui.window.devicePixelRatio,
|
||||
|
||||
Reference in New Issue
Block a user