Skip to content

Commit

Permalink
Fix InkWell ripple visible on right click when not expected (#124386)
Browse files Browse the repository at this point in the history
Right clicking an InkWell with no secondary tap handlers will no longer cause a ripple.
  • Loading branch information
bleroux committed Apr 7, 2023
1 parent e76e9c1 commit 9f98f63
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 10 deletions.
29 changes: 19 additions & 10 deletions packages/flutter/lib/src/material/ink_well.dart
Expand Up @@ -1214,17 +1214,26 @@ class _InkResponseState extends State<_InkResponseStateWidget>
}

bool isWidgetEnabled(_InkResponseStateWidget widget) {
return _primaryButtonEnabled(widget) || _secondaryButtonEnabled(widget);
}

bool _primaryButtonEnabled(_InkResponseStateWidget widget) {
return widget.onTap != null
|| widget.onDoubleTap != null
|| widget.onLongPress != null
|| widget.onTapUp != null
|| widget.onTapDown != null
|| widget.onSecondaryTap != null
|| widget.onTapDown != null;
}

bool _secondaryButtonEnabled(_InkResponseStateWidget widget) {
return widget.onSecondaryTap != null
|| widget.onSecondaryTapUp != null
|| widget.onSecondaryTapDown != null;
}

bool get enabled => isWidgetEnabled(widget);
bool get _primaryEnabled => _primaryButtonEnabled(widget);
bool get _secondaryEnabled => _secondaryButtonEnabled(widget);

void handleMouseEnter(PointerEnterEvent event) {
_hovering = true;
Expand Down Expand Up @@ -1305,16 +1314,16 @@ class _InkResponseState extends State<_InkResponseStateWidget>
onTap: widget.excludeFromSemantics || widget.onTap == null ? null : simulateTap,
onLongPress: widget.excludeFromSemantics || widget.onLongPress == null ? null : simulateLongPress,
child: GestureDetector(
onTapDown: enabled ? handleTapDown : null,
onTapUp: enabled ? handleTapUp : null,
onTap: enabled ? handleTap : null,
onTapCancel: enabled ? handleTapCancel : null,
onTapDown: _primaryEnabled ? handleTapDown : null,
onTapUp: _primaryEnabled ? handleTapUp : null,
onTap: _primaryEnabled ? handleTap : null,
onTapCancel: _primaryEnabled ? handleTapCancel : null,
onDoubleTap: widget.onDoubleTap != null ? handleDoubleTap : null,
onLongPress: widget.onLongPress != null ? handleLongPress : null,
onSecondaryTapDown: enabled ? handleSecondaryTapDown : null,
onSecondaryTapUp: enabled ? handleSecondaryTapUp: null,
onSecondaryTap: enabled ? handleSecondaryTap : null,
onSecondaryTapCancel: enabled ? handleSecondaryTapCancel : null,
onSecondaryTapDown: _secondaryEnabled ? handleSecondaryTapDown : null,
onSecondaryTapUp: _secondaryEnabled ? handleSecondaryTapUp: null,
onSecondaryTap: _secondaryEnabled ? handleSecondaryTap : null,
onSecondaryTapCancel: _secondaryEnabled ? handleSecondaryTapCancel : null,
behavior: HitTestBehavior.opaque,
excludeFromSemantics: true,
child: widget.child,
Expand Down
26 changes: 26 additions & 0 deletions packages/flutter/test/material/ink_well_test.dart
Expand Up @@ -2137,4 +2137,30 @@ testWidgets('InkResponse radius can be updated', (WidgetTester tester) async {

expect(log, equals(<String>['secondary-tap-down', 'secondary-tap-cancel']));
});

// Regression test for https://github.com/flutter/flutter/issues/124328.
testWidgets('InkWell secondary tap should not draw a splash when no secondary callbacks are defined', (WidgetTester tester) async {
await tester.pumpWidget(Directionality(
textDirection: TextDirection.ltr,
child: Material(
child: Center(
child: InkWell(
onTap: () {},
),
),
),
));

final TestGesture gesture = await tester.startGesture(
tester.getRect(find.byType(InkWell)).center,
buttons: kSecondaryButton,
);
await tester.pump(const Duration(milliseconds: 200));

// No splash should be painted.
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 0));

await gesture.up();
});
}

0 comments on commit 9f98f63

Please sign in to comment.