Skip to content

Commit bde85ea

Browse files
authored
Fix a multiple pointers bug (flutter#68587)
* Fix mutiple pointers bug * Add unit test case * Remove unnecessary map clone
1 parent 95909c2 commit bde85ea

File tree

3 files changed

+74
-7
lines changed

3 files changed

+74
-7
lines changed

packages/flutter/lib/src/gestures/monodrag.dart

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -386,12 +386,8 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
386386

387387
void _giveUpPointer(int pointer, {bool reject = true}) {
388388
stopTrackingPointer(pointer);
389-
if (reject) {
390-
if (_velocityTrackers.containsKey(pointer)) {
391-
_velocityTrackers.remove(pointer);
392-
resolvePointer(pointer, GestureDisposition.rejected);
393-
}
394-
}
389+
if (reject)
390+
resolvePointer(pointer, GestureDisposition.rejected);
395391
}
396392

397393
void _checkDown() {

packages/flutter/lib/src/gestures/recognizer.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,8 @@ abstract class OneSequenceGestureRecognizer extends GestureRecognizer {
268268
void resolvePointer(int pointer, GestureDisposition disposition) {
269269
final GestureArenaEntry? entry = _entries[pointer];
270270
if (entry != null) {
271-
entry.resolve(disposition);
272271
_entries.remove(pointer);
272+
entry.resolve(disposition);
273273
}
274274
}
275275

packages/flutter/test/gestures/drag_test.dart

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,4 +1151,75 @@ void main() {
11511151
logs.clear();
11521152
},
11531153
);
1154+
1155+
testGesture(
1156+
'On multiple pointers, the last tracking pointer can be rejected by [resolvePointer] when the '
1157+
'other pointer already accepted the VerticalDragGestureRecognizer',
1158+
(GestureTester tester) {
1159+
// Regressing test for https://github.com/flutter/flutter/issues/68373
1160+
final List<String> logs = <String>[];
1161+
final VerticalDragGestureRecognizer drag = VerticalDragGestureRecognizer()
1162+
..onDown = (DragDownDetails details) { logs.add('downD'); }
1163+
..onStart = (DragStartDetails details) { logs.add('startD'); }
1164+
..onUpdate = (DragUpdateDetails details) { logs.add('updateD'); }
1165+
..onEnd = (DragEndDetails details) { logs.add('endD'); }
1166+
..onCancel = () { logs.add('cancelD'); };
1167+
// Competitor
1168+
final TapGestureRecognizer tap = TapGestureRecognizer()
1169+
..onTapDown = (TapDownDetails details) { logs.add('downT'); }
1170+
..onTapUp = (TapUpDetails details) { logs.add('upT'); }
1171+
..onTapCancel = () {};
1172+
addTearDown(tap.dispose);
1173+
addTearDown(drag.dispose);
1174+
1175+
final TestPointer pointer1 = TestPointer(1, PointerDeviceKind.touch);
1176+
final TestPointer pointer2 = TestPointer(2, PointerDeviceKind.touch);
1177+
final TestPointer pointer3 = TestPointer(3, PointerDeviceKind.touch);
1178+
final TestPointer pointer4 = TestPointer(4, PointerDeviceKind.touch);
1179+
1180+
final PointerDownEvent down1 = pointer1.down(const Offset(10.0, 10.0));
1181+
final PointerDownEvent down2 = pointer2.down(const Offset(11.0, 11.0));
1182+
final PointerDownEvent down3 = pointer3.down(const Offset(12.0, 12.0));
1183+
final PointerDownEvent down4 = pointer4.down(const Offset(13.0, 13.0));
1184+
1185+
tap.addPointer(down1);
1186+
drag.addPointer(down1);
1187+
tester.closeArena(pointer1.pointer);
1188+
tester.route(down1);
1189+
expect(logs, <String>['downD']);
1190+
logs.clear();
1191+
1192+
tap.addPointer(down2);
1193+
drag.addPointer(down2);
1194+
tester.closeArena(pointer2.pointer);
1195+
tester.route(down2);
1196+
expect(logs, <String>[]);
1197+
1198+
tap.addPointer(down3);
1199+
drag.addPointer(down3);
1200+
tester.closeArena(pointer3.pointer);
1201+
tester.route(down3);
1202+
expect(logs, <String>[]);
1203+
1204+
drag.addPointer(down4);
1205+
tester.closeArena(pointer4.pointer);
1206+
tester.route(down4);
1207+
expect(logs, <String>['startD']);
1208+
logs.clear();
1209+
1210+
tester.route(pointer2.up());
1211+
GestureBinding.instance!.gestureArena.sweep(pointer2.pointer);
1212+
expect(logs, <String>[]);
1213+
1214+
tester.route(pointer4.cancel());
1215+
expect(logs, <String>[]);
1216+
1217+
tester.route(pointer3.cancel());
1218+
expect(logs, <String>[]);
1219+
1220+
tester.route(pointer1.cancel());
1221+
expect(logs, <String>['endD']);
1222+
logs.clear();
1223+
},
1224+
);
11541225
}

0 commit comments

Comments
 (0)