Revert "improve the scrollbar behavior when viewport size changed (#76102)" (#80059) (#80142)

Co-authored-by: Kate Lovett <katelovett@google.com>
diff --git a/packages/flutter/lib/src/widgets/scrollbar.dart b/packages/flutter/lib/src/widgets/scrollbar.dart
index 1183381..accbd59 100644
--- a/packages/flutter/lib/src/widgets/scrollbar.dart
+++ b/packages/flutter/lib/src/widgets/scrollbar.dart
@@ -276,21 +276,14 @@
   Rect? _trackRect;
   late double _thumbOffset;
 
-  /// Update with new [ScrollMetrics]. If the metrics change, the scrollbar will
-  /// show and redraw itself based on these new metrics.
+  /// Update with new [ScrollMetrics]. The scrollbar will show and redraw itself
+  /// based on these new metrics.
   ///
   /// The scrollbar will remain on screen.
   void update(
     ScrollMetrics metrics,
     AxisDirection axisDirection,
   ) {
-    if (_lastMetrics != null &&
-        _lastMetrics!.extentBefore == metrics.extentBefore &&
-        _lastMetrics!.extentInside == metrics.extentInside &&
-        _lastMetrics!.extentAfter == metrics.extentAfter &&
-        _lastAxisDirection == axisDirection)
-      return;
-
     _lastMetrics = metrics;
     _lastAxisDirection = axisDirection;
     notifyListeners();
@@ -937,90 +930,90 @@
   @override
   void didChangeDependencies() {
     super.didChangeDependencies();
-    _maybeRequestEmptyScrollEvent();
+    _maybeTriggerScrollbar();
   }
 
   // Waits one frame and cause an empty scroll event (zero delta pixels).
   //
   // This allows the thumb to show immediately when isAlwaysShown is true.
   // A scroll event is required in order to paint the thumb.
-  void _maybeRequestEmptyScrollEvent() {
-    if (!showScrollbar)
-      return;
+  void _maybeTriggerScrollbar() {
     WidgetsBinding.instance!.addPostFrameCallback((Duration duration) {
-      _fadeoutTimer?.cancel();
-      // Wait one frame and cause an empty scroll event.  This allows the
-      // thumb to show immediately when isAlwaysShown is true. A scroll
-      // event is required in order to paint the thumb.
-      final ScrollController? scrollController = widget.controller ?? PrimaryScrollController.of(context);
-      final bool tryPrimary = widget.controller == null;
-      final String controllerForError = tryPrimary
-        ? 'provided ScrollController'
-        : 'PrimaryScrollController';
-      assert(
-        scrollController != null,
-        'A ScrollController is required when Scrollbar.isAlwaysShown is true. '
-        '${tryPrimary ? 'The Scrollbar was not provided a ScrollController, '
-        'and attempted to use the PrimaryScrollController, but none was found.' :''}',
-      );
-      assert (() {
-        if (!scrollController!.hasClients) {
-          throw FlutterError.fromParts(<DiagnosticsNode>[
-            ErrorSummary(
-              'The Scrollbar\'s ScrollController has no ScrollPosition attached.',
-            ),
-            ErrorDescription(
-              'A Scrollbar cannot be painted without a ScrollPosition. ',
-            ),
-            ErrorHint(
-              'The Scrollbar attempted to use the $controllerForError. This '
-              'ScrollController should be associated with the ScrollView that '
-              'the Scrollbar is being applied to. '
-              '${tryPrimary
-                ? 'A ScrollView with an Axis.vertical '
-                  'ScrollDirection will automatically use the '
-                  'PrimaryScrollController if the user has not provided a '
-                  'ScrollController, but a ScrollDirection of Axis.horizontal will '
-                  'not. To use the PrimaryScrollController explicitly, set ScrollView.primary '
-                  'to true for the Scrollable widget.'
-                : 'When providing your own ScrollController, ensure both the '
-                  'Scrollbar and the Scrollable widget use the same one.'
-              }',
-            ),
-          ]);
-        }
-        return true;
-      }());
-      assert (() {
-        try {
-          scrollController!.position;
-        } catch (_) {
-          throw FlutterError.fromParts(<DiagnosticsNode>[
-            ErrorSummary(
-              'The $controllerForError is currently attached to more than one '
-              'ScrollPosition.',
-            ),
-            ErrorDescription(
-              'The Scrollbar requires a single ScrollPosition in order to be painted.',
-            ),
-            ErrorHint(
-              'When Scrollbar.isAlwaysShown is true, the associated Scrollable '
-              'widgets must have unique ScrollControllers. '
-              '${tryPrimary
-                ? 'The PrimaryScrollController is used by default for '
-                  'ScrollViews with an Axis.vertical ScrollDirection, '
-                  'unless the ScrollView has been provided its own '
-                  'ScrollController. More than one Scrollable may have tried '
-                  'to use the PrimaryScrollController of the current context.'
-                : 'The provided ScrollController must be unique to a '
-                  'Scrollable widget.'
-              }',
-            ),
-          ]);
-        }
-        return true;
-      }());
-      scrollController!.position.didUpdateScrollPositionBy(0);
+      if (showScrollbar) {
+        _fadeoutTimer?.cancel();
+        // Wait one frame and cause an empty scroll event.  This allows the
+        // thumb to show immediately when isAlwaysShown is true. A scroll
+        // event is required in order to paint the thumb.
+        final ScrollController? scrollController = widget.controller ?? PrimaryScrollController.of(context);
+        final bool tryPrimary = widget.controller == null;
+        final String controllerForError = tryPrimary
+          ? 'provided ScrollController'
+          : 'PrimaryScrollController';
+        assert(
+          scrollController != null,
+          'A ScrollController is required when Scrollbar.isAlwaysShown is true. '
+          '${tryPrimary ? 'The Scrollbar was not provided a ScrollController, '
+          'and attempted to use the PrimaryScrollController, but none was found.' :''}',
+        );
+        assert (() {
+          if (!scrollController!.hasClients) {
+            throw FlutterError.fromParts(<DiagnosticsNode>[
+              ErrorSummary(
+                'The Scrollbar\'s ScrollController has no ScrollPosition attached.',
+              ),
+              ErrorDescription(
+                'A Scrollbar cannot be painted without a ScrollPosition. ',
+              ),
+              ErrorHint(
+                'The Scrollbar attempted to use the $controllerForError. This '
+                'ScrollController should be associated with the ScrollView that '
+                'the Scrollbar is being applied to. '
+                '${tryPrimary
+                  ? 'A ScrollView with an Axis.vertical '
+                    'ScrollDirection will automatically use the '
+                    'PrimaryScrollController if the user has not provided a '
+                    'ScrollController, but a ScrollDirection of Axis.horizontal will '
+                    'not. To use the PrimaryScrollController explicitly, set ScrollView.primary '
+                    'to true for the Scrollable widget.'
+                  : 'When providing your own ScrollController, ensure both the '
+                    'Scrollbar and the Scrollable widget use the same one.'
+                }',
+              ),
+            ]);
+          }
+          return true;
+        }());
+        assert (() {
+          try {
+            scrollController!.position;
+          } catch (_) {
+            throw FlutterError.fromParts(<DiagnosticsNode>[
+              ErrorSummary(
+                'The $controllerForError is currently attached to more than one '
+                'ScrollPosition.',
+              ),
+              ErrorDescription(
+                'The Scrollbar requires a single ScrollPosition in order to be painted.',
+              ),
+              ErrorHint(
+                'When Scrollbar.isAlwaysShown is true, the associated Scrollable '
+                'widgets must have unique ScrollControllers. '
+                '${tryPrimary
+                  ? 'The PrimaryScrollController is used by default for '
+                    'ScrollViews with an Axis.vertical ScrollDirection, '
+                    'unless the ScrollView has been provided its own '
+                    'ScrollController. More than one Scrollable may have tried '
+                    'to use the PrimaryScrollController of the current context.'
+                  : 'The provided ScrollController must be unique to a '
+                    'Scrollable widget.'
+                }',
+              ),
+            ]);
+          }
+          return true;
+        }());
+        scrollController!.position.didUpdateScrollPositionBy(0);
+      }
     });
   }
 
@@ -1042,14 +1035,13 @@
   @override
   void didUpdateWidget(T oldWidget) {
     super.didUpdateWidget(oldWidget);
-    // If `isAlwaysShown` is true and does not change,
-    // it may be necessary to trigger a scroll event to show or hide the bar when the
-    // scrollable widget viewport size changed.
-    if (widget.isAlwaysShown == true) {
-      _maybeRequestEmptyScrollEvent();
-      _fadeoutAnimationController.animateTo(1.0);
-    } else if (widget.isAlwaysShown != oldWidget.isAlwaysShown) {
-      _fadeoutAnimationController.reverse();
+    if (widget.isAlwaysShown != oldWidget.isAlwaysShown) {
+      if (widget.isAlwaysShown == true) {
+        _maybeTriggerScrollbar();
+        _fadeoutAnimationController.animateTo(1.0);
+      } else {
+        _fadeoutAnimationController.reverse();
+      }
     }
   }
 
@@ -1211,19 +1203,13 @@
       return false;
 
     final ScrollMetrics metrics = notification.metrics;
-    if (metrics.maxScrollExtent <= metrics.minScrollExtent) {
-      // Hide the bar when the Scrollable widget has no space to scroll.
-      if (_fadeoutAnimationController.status != AnimationStatus.dismissed
-          && _fadeoutAnimationController.status != AnimationStatus.reverse)
-        _fadeoutAnimationController.reverse();
+    if (metrics.maxScrollExtent <= metrics.minScrollExtent)
       return false;
-    }
 
     if (notification is ScrollUpdateNotification ||
       notification is OverscrollNotification) {
       // Any movements always makes the scrollbar start showing up.
-      if (_fadeoutAnimationController.status != AnimationStatus.forward
-          && _fadeoutAnimationController.status != AnimationStatus.completed)
+      if (_fadeoutAnimationController.status != AnimationStatus.forward)
         _fadeoutAnimationController.forward();
 
       _fadeoutTimer?.cancel();
diff --git a/packages/flutter/test/widgets/scrollbar_test.dart b/packages/flutter/test/widgets/scrollbar_test.dart
index 69cc063..b9ac65d 100644
--- a/packages/flutter/test/widgets/scrollbar_test.dart
+++ b/packages/flutter/test/widgets/scrollbar_test.dart
@@ -1152,35 +1152,4 @@
         ),
     );
   });
-
-  testWidgets('The bar can show or hide when the viewport size change', (WidgetTester tester) async {
-    final ScrollController scrollController = ScrollController();
-    Widget buildFrame(double height) {
-      return Directionality(
-        textDirection: TextDirection.ltr,
-        child: MediaQuery(
-          data: const MediaQueryData(),
-          child: RawScrollbar(
-            controller: scrollController,
-            isAlwaysShown: true,
-            child: SingleChildScrollView(
-                controller: scrollController,
-                child: SizedBox(width: double.infinity, height: height)
-            ),
-          ),
-        ),
-      );
-    }
-    await tester.pumpWidget(buildFrame(600.0));
-    await tester.pumpAndSettle();
-    expect(find.byType(RawScrollbar), isNot(paints..rect())); // Not shown.
-
-    await tester.pumpWidget(buildFrame(600.1));
-    await tester.pumpAndSettle();
-    expect(find.byType(RawScrollbar), paints..rect()..rect()); // Show the bar.
-
-    await tester.pumpWidget(buildFrame(600.0));
-    await tester.pumpAndSettle();
-    expect(find.byType(RawScrollbar), isNot(paints..rect())); // Hide the bar.
-  });
 }