diff --git a/packages/flutter/lib/gestures.dart b/packages/flutter/lib/gestures.dart index 356d0d7fa6c..7e308941fdd 100644 --- a/packages/flutter/lib/gestures.dart +++ b/packages/flutter/lib/gestures.dart @@ -28,7 +28,6 @@ export 'src/gestures/pointer_router.dart'; export 'src/gestures/pointer_signal_resolver.dart'; export 'src/gestures/recognizer.dart'; export 'src/gestures/scale.dart'; -export 'src/gestures/semantics.dart'; export 'src/gestures/tap.dart'; export 'src/gestures/team.dart'; export 'src/gestures/velocity_tracker.dart'; diff --git a/packages/flutter/lib/src/gestures/long_press.dart b/packages/flutter/lib/src/gestures/long_press.dart index 1bacb2ce734..0c4b66c7260 100644 --- a/packages/flutter/lib/src/gestures/long_press.dart +++ b/packages/flutter/lib/src/gestures/long_press.dart @@ -6,7 +6,6 @@ import 'arena.dart'; import 'constants.dart'; import 'events.dart'; import 'recognizer.dart'; -import 'semantics.dart'; /// Callback signature for [LongPressGestureRecognizer.onLongPress]. /// @@ -215,23 +214,6 @@ class LongPressGestureRecognizer extends PrimaryPointerGestureRecognizer { /// callback. GestureLongPressEndCallback onLongPressEnd; - @override - SemanticsGestureConfiguration get semanticsConfiguration { - return _semanticsConfiguration ??= SemanticsGestureConfiguration( - onLongPress: () { - if (onLongPressStart != null) - onLongPressStart(const LongPressStartDetails()); - if (onLongPress != null) - onLongPress(); - if (onLongPressEnd != null) - onLongPressEnd(const LongPressEndDetails()); - if (onLongPressUp != null) - onLongPressUp(); - }, - ); - } - SemanticsGestureConfiguration _semanticsConfiguration; - @override bool isPointerAllowed(PointerDownEvent event) { switch (event.buttons) { diff --git a/packages/flutter/lib/src/gestures/monodrag.dart b/packages/flutter/lib/src/gestures/monodrag.dart index 38329ae884a..af235ea69a6 100644 --- a/packages/flutter/lib/src/gestures/monodrag.dart +++ b/packages/flutter/lib/src/gestures/monodrag.dart @@ -10,7 +10,6 @@ import 'constants.dart'; import 'drag_details.dart'; import 'events.dart'; import 'recognizer.dart'; -import 'semantics.dart'; import 'velocity_tracker.dart'; enum _DragState { @@ -457,23 +456,6 @@ class VerticalDragGestureRecognizer extends DragGestureRecognizer { PointerDeviceKind kind, }) : super(debugOwner: debugOwner, kind: kind); - @override - SemanticsGestureConfiguration get semanticsConfiguration { - return _semanticsConfiguration ??= SemanticsGestureConfiguration( - onVerticalDragUpdate: (DragUpdateDetails updateDetails) { - if (onDown != null) - onDown(DragDownDetails()); - if (onStart != null) - onStart(DragStartDetails()); - if (onUpdate != null) - onUpdate(updateDetails); - if (onEnd != null) - onEnd(DragEndDetails(primaryVelocity: 0.0)); - }, - ); - } - SemanticsGestureConfiguration _semanticsConfiguration; - @override bool _isFlingGesture(VelocityEstimate estimate) { final double minVelocity = minFlingVelocity ?? kMinFlingVelocity; @@ -513,23 +495,6 @@ class HorizontalDragGestureRecognizer extends DragGestureRecognizer { PointerDeviceKind kind, }) : super(debugOwner: debugOwner, kind: kind); - @override - SemanticsGestureConfiguration get semanticsConfiguration { - return _semanticsConfiguration ??= SemanticsGestureConfiguration( - onHorizontalDragUpdate: (DragUpdateDetails updateDetails) { - if (onDown != null) - onDown(DragDownDetails()); - if (onStart != null) - onStart(DragStartDetails()); - if (onUpdate != null) - onUpdate(updateDetails); - if (onEnd != null) - onEnd(DragEndDetails(primaryVelocity: 0.0)); - }, - ); - } - SemanticsGestureConfiguration _semanticsConfiguration; - @override bool _isFlingGesture(VelocityEstimate estimate) { final double minVelocity = minFlingVelocity ?? kMinFlingVelocity; @@ -563,33 +528,6 @@ class PanGestureRecognizer extends DragGestureRecognizer { /// Create a gesture recognizer for tracking movement on a plane. PanGestureRecognizer({ Object debugOwner }) : super(debugOwner: debugOwner); - @override - SemanticsGestureConfiguration get semanticsConfiguration { - return _semanticsConfiguration ??= SemanticsGestureConfiguration( - onHorizontalDragUpdate: (DragUpdateDetails updateDetails) { - if (onDown != null) - onDown(DragDownDetails()); - if (onStart != null) - onStart(DragStartDetails()); - if (onUpdate != null) - onUpdate(updateDetails); - if (onEnd != null) - onEnd(DragEndDetails()); - }, - onVerticalDragUpdate: (DragUpdateDetails updateDetails) { - if (onDown != null) - onDown(DragDownDetails()); - if (onStart != null) - onStart(DragStartDetails()); - if (onUpdate != null) - onUpdate(updateDetails); - if (onEnd != null) - onEnd(DragEndDetails()); - }, - ); - } - SemanticsGestureConfiguration _semanticsConfiguration; - @override bool _isFlingGesture(VelocityEstimate estimate) { final double minVelocity = minFlingVelocity ?? kMinFlingVelocity; diff --git a/packages/flutter/lib/src/gestures/recognizer.dart b/packages/flutter/lib/src/gestures/recognizer.dart index 6492ff71367..53f9bd6ba58 100644 --- a/packages/flutter/lib/src/gestures/recognizer.dart +++ b/packages/flutter/lib/src/gestures/recognizer.dart @@ -15,7 +15,6 @@ import 'constants.dart'; import 'debug.dart'; import 'events.dart'; import 'pointer_router.dart'; -import 'semantics.dart'; import 'team.dart'; export 'pointer_router.dart' show PointerRouter; @@ -143,21 +142,6 @@ abstract class GestureRecognizer extends GestureArenaMember with DiagnosticableT return _pointerToKind[pointer]; } - /// Returns the semantics configuration of this gesture recognizer, for example - /// for accessibility purposes. It is queried by the recognizer's - /// [RawGestureDetector] to build a collective semantics annotation. - /// - /// This method should be overridden by subclasses that are interested in - /// semantic gestures. - /// - /// The returned [SemanticsGestureConfiguration] object should be annotated in - /// a manner that describes the current state, and should remain consistant - /// behaviors across different calls. It is recommended to cache the returned - /// object. - SemanticsGestureConfiguration get semanticsConfiguration { - return null; - } - /// Releases any resources used by the object. /// /// This method is called by the owner of this gesture recognizer diff --git a/packages/flutter/lib/src/gestures/semantics.dart b/packages/flutter/lib/src/gestures/semantics.dart deleted file mode 100644 index ff63f6269f5..00000000000 --- a/packages/flutter/lib/src/gestures/semantics.dart +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2019 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 'drag_details.dart'; - -/// Called when the user taps with a semantics device. -typedef SemanticsTapCallback = void Function(); -/// Called when the user presses for a long period of time with a semantics -/// device. -typedef SemanticsLongPressCallback = void Function(); -/// Called when the user drags with a semantics device. -typedef SemanticsDragUpdateCallback = void Function(DragUpdateDetails details); - -/// Describes the semantics configuration of a gesture recognizer, for example -/// for accessibility purposes. It is queried by the recognizer's -/// [RawGestureDetector] to build a collective semantics annotation. -/// -/// When a [RawGestureDetector] receives a semantics gesture, it will invoke -/// the corresponding method that each recognizer reports in the configuration. -/// -/// See also: -/// -/// * [GestureRecognizer.semanticsConfiguration], a method that returns this -/// class. -class SemanticsGestureConfiguration { - /// Initialize the semantics handler configuration by declaring the handlers - /// for each kind of semantics events. - SemanticsGestureConfiguration({ - this.onTap, - this.onLongPress, - this.onHorizontalDragUpdate, - this.onVerticalDragUpdate, - }); - - /// Called when the user taps with a semantics device. - /// - /// See also: - /// - /// * [RenderSemanticsGestureHandler.onTap], which calls this handler with - /// the help of [RawGestureRecognizer]. - final SemanticsTapCallback onTap; - - /// Called when the user presses for a long period of time with a semantics - /// device. - /// - /// See also: - /// - /// * [RenderSemanticsGestureHandler.onLongPress], which calls this handler - /// with the help of [RawGestureRecognizer]. - final SemanticsLongPressCallback onLongPress; - - /// Called when the user scrolls to the left or to the right with a semantics - /// device. - /// - /// See also: - /// - /// * [RenderSemanticsGestureHandler.onHorizontalDragUpdate], which calls - /// this handler with the help of [RawGestureRecognizer]. - final SemanticsDragUpdateCallback onHorizontalDragUpdate; - - /// Called when the user scrolls up or down with a semantics device. - /// - /// See also: - /// - /// * [RenderSemanticsGestureHandler.onVerticalDragUpdate], which calls - /// this handler with the help of [RawGestureRecognizer]. - final SemanticsDragUpdateCallback onVerticalDragUpdate; -} diff --git a/packages/flutter/lib/src/gestures/tap.dart b/packages/flutter/lib/src/gestures/tap.dart index b4ab40808d9..f23a64466df 100644 --- a/packages/flutter/lib/src/gestures/tap.dart +++ b/packages/flutter/lib/src/gestures/tap.dart @@ -8,7 +8,6 @@ import 'arena.dart'; import 'constants.dart'; import 'events.dart'; import 'recognizer.dart'; -import 'semantics.dart'; /// Details for [GestureTapDownCallback], such as position /// @@ -238,25 +237,6 @@ class TapGestureRecognizer extends PrimaryPointerGestureRecognizer { // different set of buttons, the gesture is canceled. int _initialButtons; - @override - SemanticsGestureConfiguration get semanticsConfiguration { - // This method must always return a non-null configuration with a non-null - // onTap, even when there are no handlers related to semantics, because the - // handler properties are mutable, and assigning properties will not notify - // RawGestureDetector to update its combined configuration. - return _semanticsConfiguration ??= SemanticsGestureConfiguration( - onTap: () { - if (onTapDown != null) - onTapDown(TapDownDetails()); - if (onTapUp != null) - onTapUp(TapUpDetails()); - if (onTap != null) - onTap(); - }, - ); - } - SemanticsGestureConfiguration _semanticsConfiguration; - @override bool isPointerAllowed(PointerDownEvent event) { switch (event.buttons) { diff --git a/packages/flutter/lib/src/rendering/proxy_box.dart b/packages/flutter/lib/src/rendering/proxy_box.dart index a984f4a40c9..7a6bf1ed519 100644 --- a/packages/flutter/lib/src/rendering/proxy_box.dart +++ b/packages/flutter/lib/src/rendering/proxy_box.dart @@ -3234,10 +3234,10 @@ class RenderSemanticsGestureHandler extends RenderProxyBox { /// The [scrollFactor] argument must not be null. RenderSemanticsGestureHandler({ RenderBox child, - SemanticsTapCallback onTap, - SemanticsLongPressCallback onLongPress, - SemanticsDragUpdateCallback onHorizontalDragUpdate, - SemanticsDragUpdateCallback onVerticalDragUpdate, + GestureTapCallback onTap, + GestureLongPressCallback onLongPress, + GestureDragUpdateCallback onHorizontalDragUpdate, + GestureDragUpdateCallback onVerticalDragUpdate, this.scrollFactor = 0.8, }) : assert(scrollFactor != null), _onTap = onTap, @@ -3269,9 +3269,9 @@ class RenderSemanticsGestureHandler extends RenderProxyBox { } /// Called when the user taps on the render object. - SemanticsTapCallback get onTap => _onTap; - SemanticsTapCallback _onTap; - set onTap(SemanticsTapCallback value) { + GestureTapCallback get onTap => _onTap; + GestureTapCallback _onTap; + set onTap(GestureTapCallback value) { if (_onTap == value) return; final bool hadHandler = _onTap != null; @@ -3281,9 +3281,9 @@ class RenderSemanticsGestureHandler extends RenderProxyBox { } /// Called when the user presses on the render object for a long period of time. - SemanticsLongPressCallback get onLongPress => _onLongPress; - SemanticsLongPressCallback _onLongPress; - set onLongPress(SemanticsLongPressCallback value) { + GestureLongPressCallback get onLongPress => _onLongPress; + GestureLongPressCallback _onLongPress; + set onLongPress(GestureLongPressCallback value) { if (_onLongPress == value) return; final bool hadHandler = _onLongPress != null; @@ -3293,9 +3293,9 @@ class RenderSemanticsGestureHandler extends RenderProxyBox { } /// Called when the user scrolls to the left or to the right. - SemanticsDragUpdateCallback get onHorizontalDragUpdate => _onHorizontalDragUpdate; - SemanticsDragUpdateCallback _onHorizontalDragUpdate; - set onHorizontalDragUpdate(SemanticsDragUpdateCallback value) { + GestureDragUpdateCallback get onHorizontalDragUpdate => _onHorizontalDragUpdate; + GestureDragUpdateCallback _onHorizontalDragUpdate; + set onHorizontalDragUpdate(GestureDragUpdateCallback value) { if (_onHorizontalDragUpdate == value) return; final bool hadHandler = _onHorizontalDragUpdate != null; @@ -3305,9 +3305,9 @@ class RenderSemanticsGestureHandler extends RenderProxyBox { } /// Called when the user scrolls up or down. - SemanticsDragUpdateCallback get onVerticalDragUpdate => _onVerticalDragUpdate; - SemanticsDragUpdateCallback _onVerticalDragUpdate; - set onVerticalDragUpdate(SemanticsDragUpdateCallback value) { + GestureDragUpdateCallback get onVerticalDragUpdate => _onVerticalDragUpdate; + GestureDragUpdateCallback _onVerticalDragUpdate; + set onVerticalDragUpdate(GestureDragUpdateCallback value) { if (_onVerticalDragUpdate == value) return; final bool hadHandler = _onVerticalDragUpdate != null; diff --git a/packages/flutter/lib/src/widgets/gesture_detector.dart b/packages/flutter/lib/src/widgets/gesture_detector.dart index 4afb68062c7..e916ec35548 100644 --- a/packages/flutter/lib/src/widgets/gesture_detector.dart +++ b/packages/flutter/lib/src/widgets/gesture_detector.dart @@ -105,87 +105,6 @@ class GestureRecognizerFactoryWithHandlers extends void initializer(T instance) => _initializer(instance); } -// Retrieve semantics handlers from the given recognizers and combine them into -// collective callbacks, one for each kind of semantics gesture. -// -// This class stores the handlers instead of the recognizers, therefore any -// change to the recognzier list needs to be followed by [buildHandlers]. -class _CombinedSemanticsHandlers { - _CombinedSemanticsHandlers({ - Iterable recognizers, - }) { - buildHandlers(recognizers); - } - - final List _tapHandlers = []; - final List _longPressHandlers = - []; - final List _horizontalHandlers = - []; - final List _verticalHandlers = - []; - - // The following getters of handlers return null unless any recognizers - // show interest in the corresponding kind of semantics gestures. - SemanticsTapCallback get onTap { - return _tapHandlers.isEmpty ? null : _handleTap; - } - SemanticsLongPressCallback get onLongPress { - return _longPressHandlers.isEmpty ? null : _handleLongPress; - } - SemanticsDragUpdateCallback get onHorizontalDragUpdate { - return _horizontalHandlers.isEmpty ? null : _handleHorizontalDragUpdate; - } - SemanticsDragUpdateCallback get onVerticalDragUpdate { - return _verticalHandlers.isEmpty ? null : _handleVerticalDragUpdate; - } - - // Clear internal cache of lists of callbacks, and build anew from the given - // recognziers. - void buildHandlers(Iterable recognizers) { - _tapHandlers.clear(); - _longPressHandlers.clear(); - _horizontalHandlers.clear(); - _verticalHandlers.clear(); - if (recognizers == null) - return; - for (GestureRecognizer recognizer in recognizers) { - final SemanticsGestureConfiguration configuration = - recognizer.semanticsConfiguration; - if (configuration == null) - continue; - if (configuration.onTap != null) - _tapHandlers.add(configuration.onTap); - if (configuration.onLongPress != null) - _longPressHandlers.add(configuration.onLongPress); - if (configuration.onHorizontalDragUpdate != null) - _horizontalHandlers.add(configuration.onHorizontalDragUpdate); - if (configuration.onVerticalDragUpdate != null) - _verticalHandlers.add(configuration.onVerticalDragUpdate); - } - } - - void _handleTap() { - for (SemanticsTapCallback callback in _tapHandlers) - callback(); - } - - void _handleLongPress() { - for (SemanticsTapCallback callback in _longPressHandlers) - callback(); - } - - void _handleHorizontalDragUpdate(DragUpdateDetails details) { - for (SemanticsDragUpdateCallback callback in _horizontalHandlers) - callback(details); - } - - void _handleVerticalDragUpdate(DragUpdateDetails details) { - for (SemanticsDragUpdateCallback callback in _verticalHandlers) - callback(details); - } -} - /// A widget that detects gestures. /// /// Attempts to recognize gestures that correspond to its non-null callbacks. @@ -892,8 +811,6 @@ class RawGestureDetector extends StatefulWidget { /// State for a [RawGestureDetector]. class RawGestureDetectorState extends State { Map _recognizers = const {}; - final _CombinedSemanticsHandlers _semanticsHandlers = - _CombinedSemanticsHandlers(); @override void initState() { @@ -995,7 +912,6 @@ class RawGestureDetectorState extends State { if (!_recognizers.containsKey(type)) oldRecognizers[type].dispose(); } - _semanticsHandlers.buildHandlers(_recognizers.values); } void _handlePointerDown(PointerDownEvent event) { @@ -1008,6 +924,92 @@ class RawGestureDetectorState extends State { return widget.child == null ? HitTestBehavior.translucent : HitTestBehavior.deferToChild; } + void _handleSemanticsTap() { + final TapGestureRecognizer recognizer = _recognizers[TapGestureRecognizer]; + assert(recognizer != null); + if (recognizer.onTapDown != null) + recognizer.onTapDown(TapDownDetails()); + if (recognizer.onTapUp != null) + recognizer.onTapUp(TapUpDetails()); + if (recognizer.onTap != null) + recognizer.onTap(); + } + + void _handleSemanticsLongPress() { + final LongPressGestureRecognizer recognizer = _recognizers[LongPressGestureRecognizer]; + assert(recognizer != null); + if (recognizer.onLongPressStart != null) + recognizer.onLongPressStart(const LongPressStartDetails()); + if (recognizer.onLongPress != null) + recognizer.onLongPress(); + if (recognizer.onLongPressEnd != null) + recognizer.onLongPressEnd(const LongPressEndDetails()); + if (recognizer.onLongPressUp != null) + recognizer.onLongPressUp(); + } + + void _handleSemanticsHorizontalDragUpdate(DragUpdateDetails updateDetails) { + { + final HorizontalDragGestureRecognizer recognizer = _recognizers[HorizontalDragGestureRecognizer]; + if (recognizer != null) { + if (recognizer.onDown != null) + recognizer.onDown(DragDownDetails()); + if (recognizer.onStart != null) + recognizer.onStart(DragStartDetails()); + if (recognizer.onUpdate != null) + recognizer.onUpdate(updateDetails); + if (recognizer.onEnd != null) + recognizer.onEnd(DragEndDetails(primaryVelocity: 0.0)); + return; + } + } + { + final PanGestureRecognizer recognizer = _recognizers[PanGestureRecognizer]; + if (recognizer != null) { + if (recognizer.onDown != null) + recognizer.onDown(DragDownDetails()); + if (recognizer.onStart != null) + recognizer.onStart(DragStartDetails()); + if (recognizer.onUpdate != null) + recognizer.onUpdate(updateDetails); + if (recognizer.onEnd != null) + recognizer.onEnd(DragEndDetails()); + return; + } + } + } + + void _handleSemanticsVerticalDragUpdate(DragUpdateDetails updateDetails) { + { + final VerticalDragGestureRecognizer recognizer = _recognizers[VerticalDragGestureRecognizer]; + if (recognizer != null) { + if (recognizer.onDown != null) + recognizer.onDown(DragDownDetails()); + if (recognizer.onStart != null) + recognizer.onStart(DragStartDetails()); + if (recognizer.onUpdate != null) + recognizer.onUpdate(updateDetails); + if (recognizer.onEnd != null) + recognizer.onEnd(DragEndDetails(primaryVelocity: 0.0)); + return; + } + } + { + final PanGestureRecognizer recognizer = _recognizers[PanGestureRecognizer]; + if (recognizer != null) { + if (recognizer.onDown != null) + recognizer.onDown(DragDownDetails()); + if (recognizer.onStart != null) + recognizer.onStart(DragStartDetails()); + if (recognizer.onUpdate != null) + recognizer.onUpdate(updateDetails); + if (recognizer.onEnd != null) + recognizer.onEnd(DragEndDetails()); + return; + } + } + } + @override Widget build(BuildContext context) { Widget result = Listener( @@ -1066,16 +1068,21 @@ class _GestureSemantics extends SingleChildRenderObjectWidget { _updateHandlers(renderObject); } - SemanticsTapCallback get _onTapHandler { - return owner._semanticsHandlers.onTap; + GestureTapCallback get _onTapHandler { + return owner._recognizers.containsKey(TapGestureRecognizer) ? owner._handleSemanticsTap : null; } - SemanticsTapCallback get _onLongPressHandler { - return owner._semanticsHandlers.onLongPress; + + GestureTapCallback get _onLongPressHandler { + return owner._recognizers.containsKey(LongPressGestureRecognizer) ? owner._handleSemanticsLongPress : null; } - SemanticsDragUpdateCallback get _onHorizontalDragUpdateHandler { - return owner._semanticsHandlers.onHorizontalDragUpdate; + + GestureDragUpdateCallback get _onHorizontalDragUpdateHandler { + return owner._recognizers.containsKey(HorizontalDragGestureRecognizer) || + owner._recognizers.containsKey(PanGestureRecognizer) ? owner._handleSemanticsHorizontalDragUpdate : null; } - SemanticsDragUpdateCallback get _onVerticalDragUpdateHandler { - return owner._semanticsHandlers.onVerticalDragUpdate; + + GestureDragUpdateCallback get _onVerticalDragUpdateHandler { + return owner._recognizers.containsKey(VerticalDragGestureRecognizer) || + owner._recognizers.containsKey(PanGestureRecognizer) ? owner._handleSemanticsVerticalDragUpdate : null; } } diff --git a/packages/flutter/test/gestures/drag_test.dart b/packages/flutter/test/gestures/drag_test.dart index 5efc4045d9b..35a81971716 100644 --- a/packages/flutter/test/gestures/drag_test.dart +++ b/packages/flutter/test/gestures/drag_test.dart @@ -845,120 +845,4 @@ void main() { tap.dispose(); recognized.clear(); }); - - group('Semantic gesture configuration:', () { - test('HorizontalDragGestureRecognizer\'s semantic handlers are correctly called', () { - final List logs = []; - final HorizontalDragGestureRecognizer drag = HorizontalDragGestureRecognizer() - ..onDown = (_) { logs.add('onDown'); } - ..onStart = (_) { logs.add('onStart'); } - ..onUpdate = (_) { logs.add('onUpdate'); } - ..onEnd = (_) { logs.add('onEnd'); }; - final SemanticsGestureConfiguration configuration = drag.semanticsConfiguration; - - expect(configuration, isNotNull); - expect(configuration.onTap, isNull); - expect(configuration.onLongPress, isNull); - expect(configuration.onHorizontalDragUpdate, isNotNull); - expect(configuration.onVerticalDragUpdate, isNull); - - configuration.onHorizontalDragUpdate(DragUpdateDetails( - globalPosition: const Offset(11, 13), - )); - expect(logs, ['onDown', 'onStart', 'onUpdate', 'onEnd']); - logs.clear(); - - // Assigning handler should update the configuration handler's behavior but - // keep the configuration object - drag..onDown = null - ..onStart = null - ..onUpdate = null - ..onEnd = null; - final SemanticsGestureConfiguration configuration2 = drag.semanticsConfiguration; - expect(configuration, same(configuration2)); - configuration.onHorizontalDragUpdate(DragUpdateDetails( - globalPosition: const Offset(12, 14), - )); - expect(logs, []); - }); - - test('VerticalDragGestureRecognizer\'s semantic handlers are correctly called', () { - final List logs = []; - final VerticalDragGestureRecognizer drag = VerticalDragGestureRecognizer() - ..onDown = (_) { logs.add('onDown'); } - ..onStart = (_) { logs.add('onStart'); } - ..onUpdate = (_) { logs.add('onUpdate'); } - ..onEnd = (_) { logs.add('onEnd'); }; - final SemanticsGestureConfiguration configuration = drag.semanticsConfiguration; - - expect(configuration, isNotNull); - expect(configuration.onTap, isNull); - expect(configuration.onLongPress, isNull); - expect(configuration.onHorizontalDragUpdate, isNull); - expect(configuration.onVerticalDragUpdate, isNotNull); - - configuration.onVerticalDragUpdate(DragUpdateDetails( - globalPosition: const Offset(11, 13), - )); - expect(logs, ['onDown', 'onStart', 'onUpdate', 'onEnd']); - logs.clear(); - - // Assigning handler should update the configuration handler's behavior but - // keep the configuration object - drag..onDown = null - ..onStart = null - ..onUpdate = null - ..onEnd = null; - final SemanticsGestureConfiguration configuration2 = drag.semanticsConfiguration; - expect(configuration, same(configuration2)); - configuration.onVerticalDragUpdate(DragUpdateDetails( - globalPosition: const Offset(12, 14), - )); - expect(logs, []); - }); - - test('PanGestureRecognizer\'s semantic handlers are correctly called', () { - final List logs = []; - final PanGestureRecognizer drag = PanGestureRecognizer() - ..onDown = (_) { logs.add('onDown'); } - ..onStart = (_) { logs.add('onStart'); } - ..onUpdate = (_) { logs.add('onUpdate'); } - ..onEnd = (_) { logs.add('onEnd'); }; - final SemanticsGestureConfiguration configuration = drag.semanticsConfiguration; - - expect(configuration, isNotNull); - expect(configuration.onTap, isNull); - expect(configuration.onLongPress, isNull); - expect(configuration.onHorizontalDragUpdate, isNotNull); - expect(configuration.onVerticalDragUpdate, isNotNull); - - configuration.onVerticalDragUpdate(DragUpdateDetails( - globalPosition: const Offset(11, 13), - )); - expect(logs, ['onDown', 'onStart', 'onUpdate', 'onEnd']); - logs.clear(); - - configuration.onHorizontalDragUpdate(DragUpdateDetails( - globalPosition: const Offset(11, 13), - )); - expect(logs, ['onDown', 'onStart', 'onUpdate', 'onEnd']); - logs.clear(); - - // Assigning handler should update the configuration handler's behavior but - // keep the configuration object - drag..onDown = null - ..onStart = null - ..onUpdate = null - ..onEnd = null; - final SemanticsGestureConfiguration configuration2 = drag.semanticsConfiguration; - expect(configuration, same(configuration2)); - configuration.onVerticalDragUpdate(DragUpdateDetails( - globalPosition: const Offset(12, 14), - )); - configuration.onHorizontalDragUpdate(DragUpdateDetails( - globalPosition: const Offset(12, 14), - )); - expect(logs, []); - }); - }); } diff --git a/packages/flutter/test/gestures/long_press_test.dart b/packages/flutter/test/gestures/long_press_test.dart index 7a6630d4ff0..746ba6b3043 100644 --- a/packages/flutter/test/gestures/long_press_test.dart +++ b/packages/flutter/test/gestures/long_press_test.dart @@ -588,35 +588,4 @@ void main() { longPress.dispose(); recognized.clear(); }); - - test('Semantic onLongPress correctly calls handlers', () { - final List logs = []; - final LongPressGestureRecognizer longPress = LongPressGestureRecognizer() - ..onLongPressStart = (_) { logs.add('onLongPressStart'); } - ..onLongPress = () { logs.add('onLongPress'); } - ..onLongPressEnd = (_) { logs.add('onLongPressEnd'); } - ..onLongPressUp = () { logs.add('onLongPressUp'); }; - final SemanticsGestureConfiguration configuration = longPress.semanticsConfiguration; - - expect(configuration, isNotNull); - expect(configuration.onTap, isNull); - expect(configuration.onLongPress, isNotNull); - expect(configuration.onHorizontalDragUpdate, isNull); - expect(configuration.onVerticalDragUpdate, isNull); - - configuration.onLongPress(); - expect(logs, ['onLongPressStart', 'onLongPress', 'onLongPressEnd', 'onLongPressUp']); - logs.clear(); - - // Assigning handler should update the configuration handler's behavior but - // keep the configuration object - longPress..onLongPressStart = null - ..onLongPress = null - ..onLongPressEnd = null - ..onLongPressUp = null; - final SemanticsGestureConfiguration configuration2 = longPress.semanticsConfiguration; - expect(configuration, same(configuration2)); - configuration.onLongPress(); - expect(logs, []); - }); } diff --git a/packages/flutter/test/gestures/tap_test.dart b/packages/flutter/test/gestures/tap_test.dart index 50b4f006ea2..2d377d65063 100644 --- a/packages/flutter/test/gestures/tap_test.dart +++ b/packages/flutter/test/gestures/tap_test.dart @@ -799,33 +799,4 @@ void main() { expect(recognized, ['secondaryCancel']); }); }); - - test('Semantic onTap correctly calls handlers', () { - final List logs = []; - final TapGestureRecognizer tap = TapGestureRecognizer() - ..onTapDown = (_) { logs.add('onTapDown'); } - ..onTapUp = (_) { logs.add('onTapUp'); } - ..onTap = () { logs.add('onTap'); }; - final SemanticsGestureConfiguration configuration = tap.semanticsConfiguration; - - expect(configuration, isNotNull); - expect(configuration.onTap, isNotNull); - expect(configuration.onLongPress, isNull); - expect(configuration.onHorizontalDragUpdate, isNull); - expect(configuration.onVerticalDragUpdate, isNull); - - configuration.onTap(); - expect(logs, ['onTapDown', 'onTapUp', 'onTap']); - logs.clear(); - - // Assigning handler should update the configuration handler's behavior but - // keep the configuration object - tap..onTapDown = null - ..onTapUp = null - ..onTap = null; - final SemanticsGestureConfiguration configuration2 = tap.semanticsConfiguration; - expect(configuration, same(configuration2)); - configuration.onTap(); - expect(logs, []); - }); } diff --git a/packages/flutter/test/widgets/gesture_detector_semantics_test.dart b/packages/flutter/test/widgets/gesture_detector_semantics_test.dart index 7a7550ce33e..e616be36e3c 100644 --- a/packages/flutter/test/widgets/gesture_detector_semantics_test.dart +++ b/packages/flutter/test/widgets/gesture_detector_semantics_test.dart @@ -2,7 +2,6 @@ // 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 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; @@ -77,124 +76,4 @@ void main() { semantics.dispose(); }); - - testWidgets('All registered handlers for the gesture kind are called', (WidgetTester tester) async { - final SemanticsTester semantics = SemanticsTester(tester); - - final Set logs = {}; - final GlobalKey detectorKey = GlobalKey(); - - await tester.pumpWidget( - Center( - child: GestureDetector( - key: detectorKey, - onHorizontalDragStart: (_) { logs.add('horizontal'); }, - onPanStart: (_) { logs.add('pan'); }, - child: Container(), - ), - ), - ); - - final int detectorId = detectorKey.currentContext.findRenderObject().debugSemantics.id; - tester.binding.pipelineOwner.semanticsOwner.performAction(detectorId, SemanticsAction.scrollLeft); - expect(logs, {'horizontal', 'pan'}); - - semantics.dispose(); - }); - - testWidgets('Replacing recognizers should update semantic handlers', (WidgetTester tester) async { - final SemanticsTester semantics = SemanticsTester(tester); - - // How the test is set up: - // - Base state: RawGestureDetector with a HorizontalGR - // - Calling `introduceLayoutPerformer()` adds a `TestLayoutPerformer` as - // child of RawGestureDetector. - // - TestLayoutPerformer calls RawGestureDetector.replaceGestureRecognizers - // during layout phase, which replaces the recognizers with a TapGR. - - final Set logs = {}; - final GlobalKey detectorKey = GlobalKey(); - final VoidCallback performLayout = () { - detectorKey.currentState.replaceGestureRecognizers({ - TapGestureRecognizer: GestureRecognizerFactoryWithHandlers( - () => TapGestureRecognizer(), - (TapGestureRecognizer instance) { - instance - ..onTap = () { logs.add('tap'); }; - }, - ) - }); - }; - - bool hasLayoutPerformer = false; - VoidCallback introduceLayoutPerformer; - await tester.pumpWidget( - StatefulBuilder( - builder: (BuildContext context, StateSetter setter) { - introduceLayoutPerformer = () { - setter(() { - hasLayoutPerformer = true; - }); - }; - return Center( - child: RawGestureDetector( - key: detectorKey, - gestures: { - HorizontalDragGestureRecognizer: GestureRecognizerFactoryWithHandlers( - () => HorizontalDragGestureRecognizer(), - (HorizontalDragGestureRecognizer instance) { - instance - ..onStart = (_) { logs.add('horizontal'); }; - }, - ) - }, - child: hasLayoutPerformer ? TestLayoutPerformer(performLayout: performLayout) : null, - ), - ); - }, - ), - ); - - final int detectorId = detectorKey.currentContext.findRenderObject().debugSemantics.id; - tester.binding.pipelineOwner.semanticsOwner.performAction(detectorId, SemanticsAction.scrollLeft); - expect(logs, {'horizontal'}); - logs.clear(); - - introduceLayoutPerformer(); - await tester.pumpAndSettle(); - - tester.binding.pipelineOwner.semanticsOwner.performAction(detectorId, SemanticsAction.scrollLeft); - tester.binding.pipelineOwner.semanticsOwner.performAction(detectorId, SemanticsAction.tap); - expect(logs, {'tap'}); - logs.clear(); - - semantics.dispose(); - }); -} - -class TestLayoutPerformer extends SingleChildRenderObjectWidget { - const TestLayoutPerformer({ - Key key, - this.performLayout, - }) : super(key: key); - - final VoidCallback performLayout; - - @override - RenderTestLayoutPerformer createRenderObject(BuildContext context) { - return RenderTestLayoutPerformer(performLayout: performLayout); - } -} - -class RenderTestLayoutPerformer extends RenderBox { - RenderTestLayoutPerformer({VoidCallback performLayout}) : _performLayout = performLayout; - - VoidCallback _performLayout; - - @override - void performLayout() { - size = const Size(1, 1); - if (_performLayout != null) - _performLayout(); - } }