diff --git a/packages/flutter/lib/src/material/button_style_button.dart b/packages/flutter/lib/src/material/button_style_button.dart index be4015614c722..74cf34c3f6916 100644 --- a/packages/flutter/lib/src/material/button_style_button.dart +++ b/packages/flutter/lib/src/material/button_style_button.dart @@ -482,7 +482,7 @@ class _ButtonStyleState extends State with TickerProviderStat elevation = resolvedElevation; backgroundColor = resolvedBackgroundColor; - Widget effectiveChild = Padding( + Widget result = Padding( padding: padding, child: Align( alignment: resolvedAlignment!, @@ -494,54 +494,40 @@ class _ButtonStyleState extends State with TickerProviderStat ), ); if (resolvedBackgroundBuilder != null) { - effectiveChild = resolvedBackgroundBuilder(context, statesController.value, effectiveChild); + result = resolvedBackgroundBuilder(context, statesController.value, result); } + result = InkWell( + onTap: widget.onPressed, + onLongPress: widget.onLongPress, + onHover: widget.onHover, + mouseCursor: mouseCursor, + enableFeedback: resolvedEnableFeedback, + focusNode: widget.focusNode, + canRequestFocus: widget.enabled, + onFocusChange: widget.onFocusChange, + autofocus: widget.autofocus, + splashFactory: resolvedSplashFactory, + overlayColor: overlayColor, + highlightColor: Colors.transparent, + customBorder: resolvedShape!.copyWith(side: resolvedSide), + statesController: statesController, + child: IconTheme.merge( + data: IconThemeData( + color: resolvedIconColor ?? resolvedForegroundColor, + size: resolvedIconSize, + ), + child: result, + ), + ); + if (widget.tooltip != null) { - effectiveChild = Tooltip( + result = Tooltip( message: widget.tooltip, - child: effectiveChild, + child: result, ); } - final Widget result = ConstrainedBox( - constraints: effectiveConstraints, - child: Material( - elevation: resolvedElevation!, - textStyle: resolvedTextStyle?.copyWith(color: resolvedForegroundColor), - shape: resolvedShape!.copyWith(side: resolvedSide), - color: resolvedBackgroundColor, - shadowColor: resolvedShadowColor, - surfaceTintColor: resolvedSurfaceTintColor, - type: resolvedBackgroundColor == null ? MaterialType.transparency : MaterialType.button, - animationDuration: resolvedAnimationDuration, - clipBehavior: effectiveClipBehavior, - child: InkWell( - onTap: widget.onPressed, - onLongPress: widget.onLongPress, - onHover: widget.onHover, - mouseCursor: mouseCursor, - enableFeedback: resolvedEnableFeedback, - focusNode: widget.focusNode, - canRequestFocus: widget.enabled, - onFocusChange: widget.onFocusChange, - autofocus: widget.autofocus, - splashFactory: resolvedSplashFactory, - overlayColor: overlayColor, - highlightColor: Colors.transparent, - customBorder: resolvedShape.copyWith(side: resolvedSide), - statesController: statesController, - child: IconTheme.merge( - data: IconThemeData( - color: resolvedIconColor ?? resolvedForegroundColor, - size: resolvedIconSize, - ), - child: effectiveChild, - ), - ), - ), - ); - final Size minSize; switch (resolvedTapTargetSize!) { case MaterialTapTargetSize.padded: @@ -561,7 +547,21 @@ class _ButtonStyleState extends State with TickerProviderStat enabled: widget.enabled, child: _InputPadding( minSize: minSize, - child: result, + child: ConstrainedBox( + constraints: effectiveConstraints, + child: Material( + elevation: resolvedElevation!, + textStyle: resolvedTextStyle?.copyWith(color: resolvedForegroundColor), + shape: resolvedShape.copyWith(side: resolvedSide), + color: resolvedBackgroundColor, + shadowColor: resolvedShadowColor, + surfaceTintColor: resolvedSurfaceTintColor, + type: resolvedBackgroundColor == null ? MaterialType.transparency : MaterialType.button, + animationDuration: resolvedAnimationDuration, + clipBehavior: effectiveClipBehavior, + child: result, + ), + ), ), ); } diff --git a/packages/flutter/lib/src/material/icon_button.dart b/packages/flutter/lib/src/material/icon_button.dart index af979f6876583..8ad862177c39f 100644 --- a/packages/flutter/lib/src/material/icon_button.dart +++ b/packages/flutter/lib/src/material/icon_button.dart @@ -778,6 +778,25 @@ class IconButton extends StatelessWidget { ), ); + result = InkResponse( + focusNode: focusNode, + autofocus: autofocus, + canRequestFocus: onPressed != null, + onTap: onPressed, + mouseCursor: mouseCursor ?? (onPressed == null ? SystemMouseCursors.basic : SystemMouseCursors.click), + enableFeedback: effectiveEnableFeedback, + focusColor: focusColor ?? theme.focusColor, + hoverColor: hoverColor ?? theme.hoverColor, + highlightColor: highlightColor ?? theme.highlightColor, + splashColor: splashColor ?? theme.splashColor, + radius: splashRadius ?? math.max( + Material.defaultSplashRadius, + (effectiveIconSize + math.min(effectivePadding.horizontal, effectivePadding.vertical)) * 0.7, + // x 0.5 for diameter -> radius and + 40% overflow derived from other Material apps. + ), + child: result, + ); + if (tooltip != null) { result = Tooltip( message: tooltip, @@ -788,24 +807,7 @@ class IconButton extends StatelessWidget { return Semantics( button: true, enabled: onPressed != null, - child: InkResponse( - focusNode: focusNode, - autofocus: autofocus, - canRequestFocus: onPressed != null, - onTap: onPressed, - mouseCursor: mouseCursor ?? (onPressed == null ? SystemMouseCursors.basic : SystemMouseCursors.click), - enableFeedback: effectiveEnableFeedback, - focusColor: focusColor ?? theme.focusColor, - hoverColor: hoverColor ?? theme.hoverColor, - highlightColor: highlightColor ?? theme.highlightColor, - splashColor: splashColor ?? theme.splashColor, - radius: splashRadius ?? math.max( - Material.defaultSplashRadius, - (effectiveIconSize + math.min(effectivePadding.horizontal, effectivePadding.vertical)) * 0.7, - // x 0.5 for diameter -> radius and + 40% overflow derived from other Material apps. - ), - child: result, - ), + child: result, ); } diff --git a/packages/flutter/test/material/app_bar_test.dart b/packages/flutter/test/material/app_bar_test.dart index 1c2ad30b74f01..d3b3acb66e830 100644 --- a/packages/flutter/test/material/app_bar_test.dart +++ b/packages/flutter/test/material/app_bar_test.dart @@ -3167,6 +3167,93 @@ void main() { expect(titleOffset.dx, backButtonOffset.dx + titleSpacing); }); + // Regression test for https://github.com/flutter/flutter/issues/152315 + testWidgets('AppBar back button navigates to previous page on tap with TooltipTriggerMode.tap', (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp( + theme: ThemeData(tooltipTheme: const TooltipThemeData(triggerMode: TooltipTriggerMode.tap)), + home: Scaffold( + body: Center( + child: Builder( + builder: (BuildContext context) { + return ElevatedButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => Scaffold( + appBar: AppBar( + title: const Text('Second Screen'), + ), + ), + ), + ); + }, + child: const Text('Go to second screen'), + ); + } + ), + ), + ), + )); + + expect(find.text('Second Screen'), findsNothing); + + await tester.tap(find.text('Go to second screen')); + await tester.pumpAndSettle(); + + expect(find.text('Second Screen'), findsOneWidget); + + await tester.tap(find.byType(BackButton)); + await tester.pumpAndSettle(); + + expect(find.text('Second Screen'), findsNothing); + }); + + // Regression test for https://github.com/flutter/flutter/issues/152315 + testWidgets('Material2 - AppBar back button navigates to previous page on tap with TooltipTriggerMode.tap', (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp( + theme: ThemeData( + useMaterial3: false, + tooltipTheme: const TooltipThemeData(triggerMode: TooltipTriggerMode.tap), + ), + home: Scaffold( + body: Center( + child: Builder( + builder: (BuildContext context) { + return ElevatedButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => Scaffold( + appBar: AppBar( + title: const Text('Second Screen'), + ), + ), + ), + ); + }, + child: const Text('Go to second screen'), + ); + } + ), + ), + ), + )); + + expect(find.text('Second Screen'), findsNothing); + + await tester.tap(find.text('Go to second screen')); + await tester.pumpAndSettle(); + + expect(find.text('Second Screen'), findsOneWidget); + + await tester.tap(find.byType(BackButton)); + await tester.pumpAndSettle(); + + expect(find.text('Second Screen'), findsNothing); + }); + group('Material 2', () { testWidgets('Material2 - AppBar draws a light system bar for a dark background', (WidgetTester tester) async { final ThemeData darkTheme = ThemeData.dark(useMaterial3: false);