diff --git a/packages/flutter/test/gestures/pointer_router_test.dart b/packages/flutter/test/gestures/pointer_router_test.dart index ac63130c91d..ae30e770bab 100644 --- a/packages/flutter/test/gestures/pointer_router_test.dart +++ b/packages/flutter/test/gestures/pointer_router_test.dart @@ -7,6 +7,8 @@ import 'package:flutter/gestures.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + test('Should route pointers', () { var callbackRan = false; void callback(PointerEvent event) { diff --git a/packages/flutter_test/lib/src/controller.dart b/packages/flutter_test/lib/src/controller.dart index 73f5be6c548..485ad062fb6 100644 --- a/packages/flutter_test/lib/src/controller.dart +++ b/packages/flutter_test/lib/src/controller.dart @@ -776,9 +776,24 @@ abstract class WidgetController { } FlutterView _viewOf(finders.FinderBase finder) { - return firstWidget( + final FlutterView? view = _maybeViewOf(finder); + if (view == null) { + throw StateError( + 'No FlutterView ancestor found for finder: ' + '${finder.toString(describeSelf: true)}', + ); + } + return view; + } + + FlutterView? _maybeViewOf(finders.FinderBase finder) { + final Iterable views = widgetList( finders.find.ancestor(of: finder, matching: finders.find.byType(View)), - ).view; + ); + if (views.isEmpty) { + return null; + } + return views.first.view; } /// Checks if `finder` exists in the tree. @@ -1041,11 +1056,13 @@ abstract class WidgetController { bool warnIfMissed = true, PointerDeviceKind kind = PointerDeviceKind.touch, }) { + final FlutterView? view = _maybeViewOf(finder); return tapAt( getCenter(finder, warnIfMissed: warnIfMissed, callee: 'tap'), pointer: pointer, buttons: buttons, kind: kind, + view: view, ); } @@ -1097,7 +1114,7 @@ abstract class WidgetController { ), ]); } - return tapAt(tapLocation, pointer: pointer, buttons: buttons); + return tapAt(tapLocation, pointer: pointer, buttons: buttons, view: ranges.single.view.view); } /// Dispatch a pointer down / pointer up sequence at the given location. @@ -1106,6 +1123,7 @@ abstract class WidgetController { int? pointer, int buttons = kPrimaryButton, PointerDeviceKind kind = PointerDeviceKind.touch, + FlutterView? view, }) { return TestAsyncUtils.guard(() async { final TestGesture gesture = await startGesture( @@ -1113,6 +1131,7 @@ abstract class WidgetController { pointer: pointer, buttons: buttons, kind: kind, + view: view, ); await gesture.up(); }); @@ -1138,12 +1157,14 @@ abstract class WidgetController { bool warnIfMissed = true, PointerDeviceKind kind = PointerDeviceKind.touch, }) { + final FlutterView? view = _maybeViewOf(finder); return TestAsyncUtils.guard(() { return startGesture( getCenter(finder, warnIfMissed: warnIfMissed, callee: 'press'), pointer: pointer, buttons: buttons, kind: kind, + view: view, ); }); } @@ -1167,11 +1188,13 @@ abstract class WidgetController { bool warnIfMissed = true, PointerDeviceKind kind = PointerDeviceKind.touch, }) { + final FlutterView? view = _maybeViewOf(finder); return longPressAt( getCenter(finder, warnIfMissed: warnIfMissed, callee: 'longPress'), pointer: pointer, buttons: buttons, kind: kind, + view: view, ); } @@ -1182,6 +1205,7 @@ abstract class WidgetController { int? pointer, int buttons = kPrimaryButton, PointerDeviceKind kind = PointerDeviceKind.touch, + FlutterView? view, }) { return TestAsyncUtils.guard(() async { final TestGesture gesture = await startGesture( @@ -1189,6 +1213,7 @@ abstract class WidgetController { pointer: pointer, buttons: buttons, kind: kind, + view: view, ); await pump(kLongPressTimeout + kPressTimeout); await gesture.up(); @@ -1253,6 +1278,7 @@ abstract class WidgetController { bool warnIfMissed = true, PointerDeviceKind deviceKind = PointerDeviceKind.touch, }) { + final FlutterView? view = _maybeViewOf(finder); return flingFrom( getCenter(finder, warnIfMissed: warnIfMissed, callee: 'fling'), offset, @@ -1263,6 +1289,7 @@ abstract class WidgetController { initialOffset: initialOffset, initialOffsetDelay: initialOffsetDelay, deviceKind: deviceKind, + view: view, ); } @@ -1283,6 +1310,7 @@ abstract class WidgetController { Offset initialOffset = Offset.zero, Duration initialOffsetDelay = const Duration(seconds: 1), PointerDeviceKind deviceKind = PointerDeviceKind.touch, + FlutterView? view, }) { assert(offset.distance > 0.0); assert(speed > 0.0); // speed is pixels/second @@ -1294,7 +1322,11 @@ abstract class WidgetController { var timeStamp = 0.0; var lastTimeStamp = timeStamp; await sendEventToBinding( - testPointer.down(startLocation, timeStamp: Duration(microseconds: timeStamp.round())), + testPointer.down( + startLocation, + timeStamp: Duration(microseconds: timeStamp.round()), + view: view, + ), ); if (initialOffset.distance > 0.0) { await sendEventToBinding( @@ -1310,7 +1342,11 @@ abstract class WidgetController { final Offset location = startLocation + initialOffset + Offset.lerp(Offset.zero, offset, i / kMoveCount)!; await sendEventToBinding( - testPointer.move(location, timeStamp: Duration(microseconds: timeStamp.round())), + testPointer.move( + location, + timeStamp: Duration(microseconds: timeStamp.round()), + view: view, + ), ); timeStamp += timeStampDelta; if (timeStamp - lastTimeStamp > frameInterval.inMicroseconds) { @@ -1319,7 +1355,10 @@ abstract class WidgetController { } } await sendEventToBinding( - testPointer.up(timeStamp: Duration(microseconds: timeStamp.round())), + testPointer.up( + timeStamp: Duration(microseconds: timeStamp.round()), + view: view, + ), ); }); } @@ -1345,6 +1384,7 @@ abstract class WidgetController { Duration initialOffsetDelay = const Duration(seconds: 1), bool warnIfMissed = true, }) { + final FlutterView? view = _maybeViewOf(finder); return trackpadFlingFrom( getCenter(finder, warnIfMissed: warnIfMissed, callee: 'fling'), offset, @@ -1354,6 +1394,7 @@ abstract class WidgetController { frameInterval: frameInterval, initialOffset: initialOffset, initialOffsetDelay: initialOffsetDelay, + view: view, ); } @@ -1374,6 +1415,7 @@ abstract class WidgetController { Duration frameInterval = const Duration(milliseconds: 16), Offset initialOffset = Offset.zero, Duration initialOffsetDelay = const Duration(seconds: 1), + FlutterView? view, }) { assert(offset.distance > 0.0); assert(speed > 0.0); // speed is pixels/second @@ -1393,6 +1435,7 @@ abstract class WidgetController { testPointer.panZoomStart( startLocation, timeStamp: Duration(microseconds: timeStamp.round()), + view: view, ), ); if (initialOffset.distance > 0.0) { @@ -1401,6 +1444,7 @@ abstract class WidgetController { startLocation, pan: initialOffset, timeStamp: Duration(microseconds: timeStamp.round()), + view: view, ), ); timeStamp += initialOffsetDelay.inMicroseconds; @@ -1413,6 +1457,7 @@ abstract class WidgetController { startLocation, pan: pan, timeStamp: Duration(microseconds: timeStamp.round()), + view: view, ), ); timeStamp += timeStampDelta; @@ -1422,7 +1467,10 @@ abstract class WidgetController { } } await sendEventToBinding( - testPointer.panZoomEnd(timeStamp: Duration(microseconds: timeStamp.round())), + testPointer.panZoomEnd( + timeStamp: Duration(microseconds: timeStamp.round()), + view: view, + ), ); }); } @@ -1532,6 +1580,7 @@ abstract class WidgetController { bool warnIfMissed = true, PointerDeviceKind kind = PointerDeviceKind.touch, }) { + final FlutterView? view = _maybeViewOf(finder); return dragFrom( getCenter(finder, warnIfMissed: warnIfMissed, callee: 'drag'), offset, @@ -1540,6 +1589,7 @@ abstract class WidgetController { touchSlopX: touchSlopX, touchSlopY: touchSlopY, kind: kind, + view: view, ); } @@ -1562,6 +1612,7 @@ abstract class WidgetController { double touchSlopX = kDragSlopDefault, double touchSlopY = kDragSlopDefault, PointerDeviceKind kind = PointerDeviceKind.touch, + FlutterView? view, }) { assert(kDragSlopDefault > kTouchSlop); return TestAsyncUtils.guard(() async { @@ -1570,6 +1621,7 @@ abstract class WidgetController { pointer: pointer, buttons: buttons, kind: kind, + view: view, ); final double xSign = offset.dx.sign; @@ -1597,17 +1649,20 @@ abstract class WidgetController { final double diffY = offsetSlope.abs() * touchSlopX * ySign; // The vector from the origin to the vertical edge. - await gesture.moveBy(Offset(signedSlopX, diffY)); + await gesture.moveBy(Offset(signedSlopX, diffY), view: view); if (offsetY.abs() <= touchSlopY) { // The drag ends on or before getting to the horizontal extension of the horizontal edge. - await gesture.moveBy(Offset(offsetX - signedSlopX, offsetY - diffY)); + await gesture.moveBy(Offset(offsetX - signedSlopX, offsetY - diffY), view: view); } else { final double diffY2 = signedSlopY - diffY; final double diffX2 = inverseOffsetSlope * diffY2; // The vector from the edge of the box to the horizontal extension of the horizontal edge. - await gesture.moveBy(Offset(diffX2, diffY2)); - await gesture.moveBy(Offset(offsetX - diffX2 - signedSlopX, offsetY - signedSlopY)); + await gesture.moveBy(Offset(diffX2, diffY2), view: view); + await gesture.moveBy( + Offset(offsetX - diffX2 - signedSlopX, offsetY - signedSlopY), + view: view, + ); } } else { assert(offsetY.abs() > touchSlopY); @@ -1616,29 +1671,32 @@ abstract class WidgetController { final double diffX = inverseOffsetSlope.abs() * touchSlopY * xSign; // The vector from the origin to the vertical edge. - await gesture.moveBy(Offset(diffX, signedSlopY)); + await gesture.moveBy(Offset(diffX, signedSlopY), view: view); if (offsetX.abs() <= touchSlopX) { // The drag ends on or before getting to the vertical extension of the vertical edge. - await gesture.moveBy(Offset(offsetX - diffX, offsetY - signedSlopY)); + await gesture.moveBy(Offset(offsetX - diffX, offsetY - signedSlopY), view: view); } else { final double diffX2 = signedSlopX - diffX; final double diffY2 = offsetSlope * diffX2; // The vector from the edge of the box to the vertical extension of the vertical edge. - await gesture.moveBy(Offset(diffX2, diffY2)); - await gesture.moveBy(Offset(offsetX - signedSlopX, offsetY - diffY2 - signedSlopY)); + await gesture.moveBy(Offset(diffX2, diffY2), view: view); + await gesture.moveBy( + Offset(offsetX - signedSlopX, offsetY - diffY2 - signedSlopY), + view: view, + ); } } } else { // The drag goes through the corner of the box. - await gesture.moveBy(Offset(signedSlopX, signedSlopY)); - await gesture.moveBy(Offset(offsetX - signedSlopX, offsetY - signedSlopY)); + await gesture.moveBy(Offset(signedSlopX, signedSlopY), view: view); + await gesture.moveBy(Offset(offsetX - signedSlopX, offsetY - signedSlopY), view: view); } } else { // The drag ends inside the box. - await gesture.moveBy(offset); + await gesture.moveBy(offset, view: view); } - await gesture.up(); + await gesture.up(view: view); }); } @@ -1670,6 +1728,7 @@ abstract class WidgetController { int buttons = kPrimaryButton, double frequency = 60.0, bool warnIfMissed = true, + FlutterView? view, }) { return timedDragFrom( getCenter(finder, warnIfMissed: warnIfMissed, callee: 'timedDrag'), @@ -1678,6 +1737,7 @@ abstract class WidgetController { pointer: pointer, buttons: buttons, frequency: frequency, + view: view, ); } @@ -1696,6 +1756,7 @@ abstract class WidgetController { int? pointer, int buttons = kPrimaryButton, double frequency = 60.0, + FlutterView? view, }) { assert(frequency > 0); final int intervals = duration.inMicroseconds * frequency ~/ 1E6; @@ -1710,13 +1771,18 @@ abstract class WidgetController { ]; final records = [ PointerEventRecord(Duration.zero, [ - PointerAddedEvent(position: startLocation), + PointerAddedEvent( + position: startLocation, + viewId: view?.viewId ?? WidgetsBinding.instance.platformDispatcher.implicitView!.viewId, + ), PointerDownEvent(position: startLocation, pointer: pointer, buttons: buttons), ]), ...[ for (int t = 0; t <= intervals; t += 1) PointerEventRecord(timeStamps[t], [ PointerMoveEvent( + viewId: + view?.viewId ?? WidgetsBinding.instance.platformDispatcher.implicitView!.viewId, timeStamp: timeStamps[t], position: offsets[t + 1], delta: offsets[t + 1] - offsets[t], @@ -1727,6 +1793,7 @@ abstract class WidgetController { ], PointerEventRecord(duration, [ PointerUpEvent( + viewId: view?.viewId ?? WidgetsBinding.instance.platformDispatcher.implicitView!.viewId, timeStamp: duration, position: offsets.last, pointer: pointer, @@ -1802,12 +1869,13 @@ abstract class WidgetController { int? pointer, PointerDeviceKind kind = PointerDeviceKind.touch, int buttons = kPrimaryButton, + FlutterView? view, }) async { final TestGesture result = _createGesture(pointer: pointer, kind: kind, buttons: buttons); if (kind == PointerDeviceKind.trackpad) { - await result.panZoomStart(downLocation); + await result.panZoomStart(downLocation, view: view); } else { - await result.down(downLocation); + await result.down(downLocation, view: view); } return result; } diff --git a/packages/flutter_test/lib/src/test_pointer.dart b/packages/flutter_test/lib/src/test_pointer.dart index 62961c5276e..68f35740c43 100644 --- a/packages/flutter_test/lib/src/test_pointer.dart +++ b/packages/flutter_test/lib/src/test_pointer.dart @@ -8,8 +8,8 @@ /// @docImport 'widget_tester.dart'; library; -import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; +import 'package:flutter/widgets.dart'; import 'test_async_utils.dart'; @@ -121,7 +121,12 @@ class TestPointer { /// /// By default, the set of buttons in the last down or move event is used. /// You can give a specific set of buttons by passing the `buttons` argument. - PointerDownEvent down(Offset newLocation, {Duration timeStamp = Duration.zero, int? buttons}) { + PointerDownEvent down( + Offset newLocation, { + Duration timeStamp = Duration.zero, + int? buttons, + FlutterView? view, + }) { assert(!isDown); assert(!isPanZoomActive); _isDown = true; @@ -130,6 +135,7 @@ class TestPointer { _buttons = buttons; } return PointerDownEvent( + viewId: view?.viewId ?? WidgetsBinding.instance.platformDispatcher.implicitView!.viewId, timeStamp: timeStamp, kind: kind, device: _device, @@ -149,7 +155,12 @@ class TestPointer { /// /// By default, the set of buttons in the last down or move event is used. /// You can give a specific set of buttons by passing the `buttons` argument. - PointerMoveEvent move(Offset newLocation, {Duration timeStamp = Duration.zero, int? buttons}) { + PointerMoveEvent move( + Offset newLocation, { + Duration timeStamp = Duration.zero, + int? buttons, + FlutterView? view, + }) { assert( isDown, 'Move events can only be generated when the pointer is down. To ' @@ -164,6 +175,7 @@ class TestPointer { } return PointerMoveEvent( timeStamp: timeStamp, + viewId: view?.viewId ?? WidgetsBinding.instance.platformDispatcher.implicitView!.viewId, kind: kind, device: _device, pointer: pointer, @@ -179,11 +191,12 @@ class TestPointer { /// specific time stamp by passing the `timeStamp` argument. /// /// The object is no longer usable after this method has been called. - PointerUpEvent up({Duration timeStamp = Duration.zero}) { + PointerUpEvent up({Duration timeStamp = Duration.zero, FlutterView? view}) { assert(!isPanZoomActive); assert(isDown); _isDown = false; return PointerUpEvent( + viewId: view?.viewId ?? WidgetsBinding.instance.platformDispatcher.implicitView!.viewId, timeStamp: timeStamp, kind: kind, device: _device, @@ -198,11 +211,12 @@ class TestPointer { /// specific time stamp by passing the `timeStamp` argument. /// /// The object is no longer usable after this method has been called. - PointerCancelEvent cancel({Duration timeStamp = Duration.zero}) { + PointerCancelEvent cancel({Duration timeStamp = Duration.zero, FlutterView? view}) { assert(isDown); _isDown = false; return PointerCancelEvent( timeStamp: timeStamp, + viewId: view?.viewId ?? WidgetsBinding.instance.platformDispatcher.implicitView!.viewId, kind: kind, device: _device, pointer: pointer, @@ -215,9 +229,14 @@ class TestPointer { /// /// By default, the time stamp on the event is [Duration.zero]. You can give a /// specific time stamp by passing the `timeStamp` argument. - PointerAddedEvent addPointer({Duration timeStamp = Duration.zero, Offset? location}) { + PointerAddedEvent addPointer({ + Duration timeStamp = Duration.zero, + Offset? location, + FlutterView? view, + }) { _location = location ?? _location; return PointerAddedEvent( + viewId: view?.viewId ?? WidgetsBinding.instance.platformDispatcher.implicitView!.viewId, timeStamp: timeStamp, kind: kind, device: _device, @@ -230,9 +249,14 @@ class TestPointer { /// /// By default, the time stamp on the event is [Duration.zero]. You can give a /// specific time stamp by passing the `timeStamp` argument. - PointerRemovedEvent removePointer({Duration timeStamp = Duration.zero, Offset? location}) { + PointerRemovedEvent removePointer({ + Duration timeStamp = Duration.zero, + Offset? location, + FlutterView? view, + }) { _location = location ?? _location; return PointerRemovedEvent( + viewId: view?.viewId ?? WidgetsBinding.instance.platformDispatcher.implicitView!.viewId, timeStamp: timeStamp, kind: kind, device: _device, @@ -248,7 +272,11 @@ class TestPointer { /// /// [isDown] must be false, since hover events can't be sent when the pointer /// is up. - PointerHoverEvent hover(Offset newLocation, {Duration timeStamp = Duration.zero}) { + PointerHoverEvent hover( + Offset newLocation, { + Duration timeStamp = Duration.zero, + FlutterView? view, + }) { assert( !isDown, 'Hover events can only be generated when the pointer is up. To ' @@ -257,6 +285,7 @@ class TestPointer { final Offset delta = location != null ? newLocation - location! : Offset.zero; _location = newLocation; return PointerHoverEvent( + viewId: view?.viewId ?? WidgetsBinding.instance.platformDispatcher.implicitView!.viewId, timeStamp: timeStamp, kind: kind, device: _device, @@ -275,10 +304,12 @@ class TestPointer { Offset scrollDelta, { Duration timeStamp = Duration.zero, RespondPointerEventCallback? onRespond, + FlutterView? view, }) { assert(kind != PointerDeviceKind.touch, "Touch pointers can't generate pointer signal events"); assert(location != null); return PointerScrollEvent( + viewId: view?.viewId ?? WidgetsBinding.instance.platformDispatcher.implicitView!.viewId, timeStamp: timeStamp, kind: kind, device: _device, @@ -292,10 +323,14 @@ class TestPointer { /// /// By default, the time stamp on the event is [Duration.zero]. You can give a /// specific time stamp by passing the `timeStamp` argument. - PointerScrollInertiaCancelEvent scrollInertiaCancel({Duration timeStamp = Duration.zero}) { + PointerScrollInertiaCancelEvent scrollInertiaCancel({ + Duration timeStamp = Duration.zero, + FlutterView? view, + }) { assert(kind != PointerDeviceKind.touch, "Touch pointers can't generate pointer signal events"); assert(location != null); return PointerScrollInertiaCancelEvent( + viewId: view?.viewId ?? WidgetsBinding.instance.platformDispatcher.implicitView!.viewId, timeStamp: timeStamp, kind: kind, device: _device, @@ -307,10 +342,11 @@ class TestPointer { /// /// By default, the time stamp on the event is [Duration.zero]. You can give a /// specific time stamp by passing the `timeStamp` argument. - PointerScaleEvent scale(double scale, {Duration timeStamp = Duration.zero}) { + PointerScaleEvent scale(double scale, {Duration timeStamp = Duration.zero, FlutterView? view}) { assert(kind != PointerDeviceKind.touch, "Touch pointers can't generate pointer signal events"); assert(location != null); return PointerScaleEvent( + viewId: view?.viewId ?? WidgetsBinding.instance.platformDispatcher.implicitView!.viewId, timeStamp: timeStamp, kind: kind, device: _device, @@ -324,13 +360,18 @@ class TestPointer { /// /// By default, the time stamp on the event is [Duration.zero]. You can give a /// specific time stamp by passing the `timeStamp` argument. - PointerPanZoomStartEvent panZoomStart(Offset location, {Duration timeStamp = Duration.zero}) { + PointerPanZoomStartEvent panZoomStart( + Offset location, { + Duration timeStamp = Duration.zero, + FlutterView? view, + }) { assert(!isPanZoomActive); assert(kind == PointerDeviceKind.trackpad); _location = location; _pan = Offset.zero; _isPanZoomActive = true; return PointerPanZoomStartEvent( + viewId: view?.viewId ?? WidgetsBinding.instance.platformDispatcher.implicitView!.viewId, timeStamp: timeStamp, device: _device, pointer: pointer, @@ -351,6 +392,7 @@ class TestPointer { double scale = 1, double rotation = 0, Duration timeStamp = Duration.zero, + FlutterView? view, }) { assert(isPanZoomActive); assert(kind == PointerDeviceKind.trackpad); @@ -358,6 +400,7 @@ class TestPointer { final Offset panDelta = pan - _pan!; _pan = pan; return PointerPanZoomUpdateEvent( + viewId: view?.viewId ?? WidgetsBinding.instance.platformDispatcher.implicitView!.viewId, timeStamp: timeStamp, device: _device, pointer: pointer, @@ -374,12 +417,13 @@ class TestPointer { /// /// By default, the time stamp on the event is [Duration.zero]. You can give a /// specific time stamp by passing the `timeStamp` argument. - PointerPanZoomEndEvent panZoomEnd({Duration timeStamp = Duration.zero}) { + PointerPanZoomEndEvent panZoomEnd({Duration timeStamp = Duration.zero, FlutterView? view}) { assert(isPanZoomActive); assert(kind == PointerDeviceKind.trackpad); _isPanZoomActive = false; _pan = null; return PointerPanZoomEndEvent( + viewId: view?.viewId ?? WidgetsBinding.instance.platformDispatcher.implicitView!.viewId, timeStamp: timeStamp, device: _device, pointer: pointer, @@ -428,13 +472,17 @@ class TestGesture { /// Dispatch a pointer down event at the given `downLocation`, caching the /// hit test result. - Future down(Offset downLocation, {Duration timeStamp = Duration.zero}) async { + Future down( + Offset downLocation, { + Duration timeStamp = Duration.zero, + FlutterView? view, + }) async { assert( _pointer.kind != PointerDeviceKind.trackpad, 'Trackpads are expected to send panZoomStart events, not down events.', ); return TestAsyncUtils.guard(() async { - return _dispatcher(_pointer.down(downLocation, timeStamp: timeStamp)); + return _dispatcher(_pointer.down(downLocation, timeStamp: timeStamp, view: view)); }); } @@ -491,16 +539,17 @@ class TestGesture { /// * [WidgetController.timedDrag], a method to simulate the drag of a given widget in a given duration. /// It sends move events at a given frequency and it is useful when there are listeners involved. /// * [WidgetController.fling], a method to simulate a fling. - Future moveBy(Offset offset, {Duration timeStamp = Duration.zero}) { + Future moveBy(Offset offset, {Duration timeStamp = Duration.zero, FlutterView? view}) { assert(_pointer.location != null); if (_pointer.isPanZoomActive) { return panZoomUpdate( _pointer.location!, pan: (_pointer.pan ?? Offset.zero) + offset, timeStamp: timeStamp, + view: view, ); } else { - return moveTo(_pointer.location! + offset, timeStamp: timeStamp); + return moveTo(_pointer.location! + offset, timeStamp: timeStamp, view: view); } } @@ -514,28 +563,28 @@ class TestGesture { /// * [WidgetController.timedDrag], a method to simulate the drag of a given widget in a given duration. /// It sends move events at a given frequency and it is useful when there are listeners involved. /// * [WidgetController.fling], a method to simulate a fling. - Future moveTo(Offset location, {Duration timeStamp = Duration.zero}) { + Future moveTo(Offset location, {Duration timeStamp = Duration.zero, FlutterView? view}) { assert(_pointer.kind != PointerDeviceKind.trackpad); return TestAsyncUtils.guard(() { if (_pointer._isDown) { - return _dispatcher(_pointer.move(location, timeStamp: timeStamp)); + return _dispatcher(_pointer.move(location, timeStamp: timeStamp, view: view)); } else { - return _dispatcher(_pointer.hover(location, timeStamp: timeStamp)); + return _dispatcher(_pointer.hover(location, timeStamp: timeStamp, view: view)); } }); } /// End the gesture by releasing the pointer. For trackpad pointers this /// will send a panZoomEnd event instead of an up event. - Future up({Duration timeStamp = Duration.zero}) { + Future up({Duration timeStamp = Duration.zero, FlutterView? view}) { return TestAsyncUtils.guard(() async { if (_pointer.kind == PointerDeviceKind.trackpad) { assert(_pointer._isPanZoomActive); - await _dispatcher(_pointer.panZoomEnd(timeStamp: timeStamp)); + await _dispatcher(_pointer.panZoomEnd(timeStamp: timeStamp, view: view)); assert(!_pointer._isPanZoomActive); } else { assert(_pointer._isDown); - await _dispatcher(_pointer.up(timeStamp: timeStamp)); + await _dispatcher(_pointer.up(timeStamp: timeStamp, view: view)); assert(!_pointer._isDown); } }); @@ -555,13 +604,17 @@ class TestGesture { /// Dispatch a pointer pan zoom start event at the given `location`, caching the /// hit test result. - Future panZoomStart(Offset location, {Duration timeStamp = Duration.zero}) async { + Future panZoomStart( + Offset location, { + Duration timeStamp = Duration.zero, + FlutterView? view, + }) async { assert( _pointer.kind == PointerDeviceKind.trackpad, 'Only trackpads can send PointerPanZoom events.', ); return TestAsyncUtils.guard(() async { - return _dispatcher(_pointer.panZoomStart(location, timeStamp: timeStamp)); + return _dispatcher(_pointer.panZoomStart(location, timeStamp: timeStamp, view: view)); }); } @@ -573,6 +626,7 @@ class TestGesture { double scale = 1, double rotation = 0, Duration timeStamp = Duration.zero, + FlutterView? view, }) async { assert( _pointer.kind == PointerDeviceKind.trackpad, @@ -586,6 +640,7 @@ class TestGesture { scale: scale, rotation: rotation, timeStamp: timeStamp, + view: view, ), ); });