diff --git a/packages/flutter/lib/src/material/ink_well.dart b/packages/flutter/lib/src/material/ink_well.dart index 94d642b460..e00de3191e 100644 --- a/packages/flutter/lib/src/material/ink_well.dart +++ b/packages/flutter/lib/src/material/ink_well.dart @@ -732,11 +732,14 @@ class _InkResponseState extends State<_InkResponseStateWidget> InteractiveInkFeature? _currentSplash; bool _hovering = false; final Map<_HighlightType, InkHighlight?> _highlights = <_HighlightType, InkHighlight?>{}; - late Map> _actionMap; + late final Map> _actionMap = >{ + ActivateIntent: CallbackAction(onInvoke: _simulateTap), + }; bool get highlightsExist => _highlights.values.where((InkHighlight? highlight) => highlight != null).isNotEmpty; final ObserverList<_ParentInkResponseState> _activeChildren = ObserverList<_ParentInkResponseState>(); + @override void markChildInkResponsePressed(_ParentInkResponseState childState, bool value) { assert(childState != null); @@ -753,17 +756,19 @@ class _InkResponseState extends State<_InkResponseStateWidget> } bool get _anyChildInkResponsePressed => _activeChildren.isNotEmpty; - void _handleAction(ActivateIntent intent) { + void _simulateTap([ActivateIntent? intent]) { _startSplash(context: context); - _handleTap(context); + _handleTap(); + } + + void _simulateLongPress() { + _startSplash(context: context); + _handleLongPress(); } @override void initState() { super.initState(); - _actionMap = >{ - ActivateIntent: CallbackAction(onInvoke: _handleAction), - }; FocusManager.instance.addHighlightModeListener(_handleFocusHighlightModeChange); } @@ -975,7 +980,7 @@ class _InkResponseState extends State<_InkResponseStateWidget> updateHighlight(_HighlightType.pressed, value: true); } - void _handleTap(BuildContext context) { + void _handleTap() { _currentSplash?.confirm(); _currentSplash = null; updateHighlight(_HighlightType.pressed, value: false); @@ -1002,7 +1007,7 @@ class _InkResponseState extends State<_InkResponseStateWidget> widget.onDoubleTap!(); } - void _handleLongPress(BuildContext context) { + void _handleLongPress() { _currentSplash?.confirm(); _currentSplash = null; if (widget.onLongPress != null) { @@ -1096,15 +1101,19 @@ class _InkResponseState extends State<_InkResponseStateWidget> cursor: effectiveMouseCursor, onEnter: _handleMouseEnter, onExit: _handleMouseExit, - child: GestureDetector( - onTapDown: enabled ? _handleTapDown : null, - onTap: enabled ? () => _handleTap(context) : null, - onTapCancel: enabled ? _handleTapCancel : null, - onDoubleTap: widget.onDoubleTap != null ? _handleDoubleTap : null, - onLongPress: widget.onLongPress != null ? () => _handleLongPress(context) : null, - behavior: HitTestBehavior.opaque, - excludeFromSemantics: widget.excludeFromSemantics, - child: widget.child, + child: Semantics( + onTap: widget.excludeFromSemantics || widget.onTap == null ? null : _simulateTap, + onLongPress: widget.excludeFromSemantics || widget.onLongPress == null ? null : _simulateLongPress, + child: GestureDetector( + onTapDown: enabled ? _handleTapDown : null, + onTap: enabled ? _handleTap : null, + onTapCancel: enabled ? _handleTapCancel : null, + onDoubleTap: widget.onDoubleTap != null ? _handleDoubleTap : null, + onLongPress: widget.onLongPress != null ? _handleLongPress : null, + behavior: HitTestBehavior.opaque, + excludeFromSemantics: true, + child: widget.child, + ), ), ), ), diff --git a/packages/flutter/test/material/ink_well_test.dart b/packages/flutter/test/material/ink_well_test.dart index 29b1b10ad2..0906bb35a4 100644 --- a/packages/flutter/test/material/ink_well_test.dart +++ b/packages/flutter/test/material/ink_well_test.dart @@ -1288,4 +1288,48 @@ void main() { await tester.pumpWidget(buildFrame(enabled: false)); await tester.pumpAndSettle(); }); + + testWidgets('InkWell does not attach semantics handler for onTap if it was not provided an onTap handler', (WidgetTester tester) async { + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: Material( + child: Center( + child: InkWell( + onLongPress: () { }, + child: const Text('Foo'), + ), + ), + ), + )); + + expect(tester.getSemantics(find.bySemanticsLabel('Foo')), matchesSemantics( + label: 'Foo', + hasTapAction: false, + hasLongPressAction: true, + isFocusable: true, + textDirection: TextDirection.ltr, + )); + + // Add tap handler and confirm addition to semantic actions. + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: Material( + child: Center( + child: InkWell( + onLongPress: () { }, + onTap: () { }, + child: const Text('Foo'), + ), + ), + ), + )); + + expect(tester.getSemantics(find.bySemanticsLabel('Foo')), matchesSemantics( + label: 'Foo', + hasTapAction: true, + hasLongPressAction: true, + isFocusable: true, + textDirection: TextDirection.ltr, + )); + }); }