Unverified Commit 6afbb25a authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Reject unaccepted pointers in Drag recognizer (#75943)

parent 46b8ea8f
......@@ -309,15 +309,16 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
}
}
if (event is PointerUpEvent || event is PointerCancelEvent) {
_giveUpPointer(
event.pointer,
reject: event is PointerCancelEvent || _state ==_DragState.possible,
);
_giveUpPointer(event.pointer);
}
}
final Set<int> _acceptedActivePointers = <int>{};
@override
void acceptGesture(int pointer) {
assert(!_acceptedActivePointers.contains(pointer));
_acceptedActivePointers.add(pointer);
if (_state != _DragState.accepted) {
_state = _DragState.accepted;
final OffsetPair delta = _pendingDragOffset;
......@@ -384,32 +385,36 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
_state = _DragState.ready;
}
void _giveUpPointer(int pointer, {bool reject = true}) {
void _giveUpPointer(int pointer) {
stopTrackingPointer(pointer);
if (reject)
// If we never accepted the pointer, we reject it since we are no longer
// interested in winning the gesture arena for it.
if (!_acceptedActivePointers.remove(pointer))
resolvePointer(pointer, GestureDisposition.rejected);
}
void _checkDown() {
assert(_initialButtons == kPrimaryButton);
final DragDownDetails details = DragDownDetails(
globalPosition: _initialPosition.global,
localPosition: _initialPosition.local,
);
if (onDown != null)
if (onDown != null) {
final DragDownDetails details = DragDownDetails(
globalPosition: _initialPosition.global,
localPosition: _initialPosition.local,
);
invokeCallback<void>('onDown', () => onDown!(details));
}
}
void _checkStart(Duration timestamp, int pointer) {
assert(_initialButtons == kPrimaryButton);
final DragStartDetails details = DragStartDetails(
sourceTimeStamp: timestamp,
globalPosition: _initialPosition.global,
localPosition: _initialPosition.local,
kind: getKindForPointer(pointer),
);
if (onStart != null)
if (onStart != null) {
final DragStartDetails details = DragStartDetails(
sourceTimeStamp: timestamp,
globalPosition: _initialPosition.global,
localPosition: _initialPosition.local,
kind: getKindForPointer(pointer),
);
invokeCallback<void>('onStart', () => onStart!(details));
}
}
void _checkUpdate({
......@@ -420,15 +425,16 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
Offset? localPosition,
}) {
assert(_initialButtons == kPrimaryButton);
final DragUpdateDetails details = DragUpdateDetails(
sourceTimeStamp: sourceTimeStamp,
delta: delta,
primaryDelta: primaryDelta,
globalPosition: globalPosition,
localPosition: localPosition,
);
if (onUpdate != null)
if (onUpdate != null) {
final DragUpdateDetails details = DragUpdateDetails(
sourceTimeStamp: sourceTimeStamp,
delta: delta,
primaryDelta: primaryDelta,
globalPosition: globalPosition,
localPosition: localPosition,
);
invokeCallback<void>('onUpdate', () => onUpdate!(details));
}
}
void _checkEnd(int pointer) {
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/gestures.dart';
import 'package:flutter_test/flutter_test.dart';
import 'gesture_tester.dart';
void main() {
setUp(ensureGestureBinding);
testGesture('do not crash on up event for a pending pointer after winning arena for another pointer', (GestureTester tester) {
// Regression test for https://github.com/flutter/flutter/issues/75061.
final VerticalDragGestureRecognizer v = VerticalDragGestureRecognizer()
..onStart = (_) { };
final HorizontalDragGestureRecognizer h = HorizontalDragGestureRecognizer()
..onStart = (_) { };
const PointerDownEvent down90 = PointerDownEvent(
pointer: 90,
position: Offset(10.0, 10.0),
);
const PointerUpEvent up90 = PointerUpEvent(
pointer: 90,
position: Offset(10.0, 10.0),
);
const PointerDownEvent down91 = PointerDownEvent(
pointer: 91,
position: Offset(20.0, 20.0),
);
const PointerUpEvent up91 = PointerUpEvent(
pointer: 91,
position: Offset(20.0, 20.0),
);
v.addPointer(down90);
GestureBinding.instance!.gestureArena.close(90);
h.addPointer(down91);
v.addPointer(down91);
GestureBinding.instance!.gestureArena.close(91);
tester.async.flushMicrotasks();
GestureBinding.instance!.handleEvent(up90, HitTestEntry(MockHitTestTarget()));
GestureBinding.instance!.handleEvent(up91, HitTestEntry(MockHitTestTarget()));
});
}
class MockHitTestTarget implements HitTestTarget {
@override
void handleEvent(PointerEvent event, HitTestEntry entry) { }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment