Skip to content

Commit

Permalink
RawScrollbar: don't listen for drag gestures when scrolling is not po…
Browse files Browse the repository at this point in the history
…ssible (#149925)

Fixes flutter/flutter#149803
  • Loading branch information
HansMuller authored Jun 13, 2024
1 parent 034966b commit 1b8dc90
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
10 changes: 9 additions & 1 deletion packages/flutter/lib/src/widgets/scrollbar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1953,9 +1953,17 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
instance.dragStartBehavior = DragStartBehavior.down;
}

bool _canHandleScrollGestures() {
return enableGestures
&& _effectiveScrollController != null
&& _effectiveScrollController!.positions.length == 1
&& _effectiveScrollController!.position.hasContentDimensions
&& _effectiveScrollController!.position.maxScrollExtent > 0.0;
}

Map<Type, GestureRecognizerFactory> get _gestures {
final Map<Type, GestureRecognizerFactory> gestures = <Type, GestureRecognizerFactory>{};
if (_effectiveScrollController == null || !enableGestures) {
if (!_canHandleScrollGestures()) {
return gestures;
}

Expand Down
44 changes: 44 additions & 0 deletions packages/flutter/test/widgets/scrollbar_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import 'dart:ui' as ui;

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/src/physics/utils.dart' show nearEqual;
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
Expand Down Expand Up @@ -3212,4 +3213,47 @@ The provided ScrollController cannot be shared by multiple ScrollView widgets.''
},
variant: TargetPlatformVariant.all(),
);

testWidgets('Safe to drag trackpad when maxScrollExtent is 0 (scrollbar is not painted)', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/149803
final ScrollController scrollController = ScrollController();
addTearDown(scrollController.dispose);

Widget buildFrame(double sizedBoxHeight) {
return Directionality(
textDirection: TextDirection.ltr,
child: MediaQuery(
data: const MediaQueryData(),
child: RawScrollbar(
controller: scrollController,
child: SingleChildScrollView(
controller: scrollController,
child: SizedBox(width: 100.0, height: sizedBoxHeight),
),
),
),
);
}

await tester.pumpWidget(buildFrame(100)); // Test viewport has height=600
await tester.pumpAndSettle();
expect(scrollController.offset, 0.0);
expect(scrollController.position.maxScrollExtent, 0.0);

await tester.drag(find.byType(SingleChildScrollView), const Offset(0, -100), kind: PointerDeviceKind.trackpad);
await tester.pumpAndSettle();
expect(scrollController.offset, 0.0);
expect(scrollController.position.maxScrollExtent, 0.0);

await tester.pumpWidget(buildFrame(700));
await tester.pumpAndSettle();
expect(scrollController.offset, 0.0);
expect(scrollController.position.maxScrollExtent, 100.0);

await tester.drag(find.byType(SingleChildScrollView), const Offset(0, -100), kind: PointerDeviceKind.trackpad);
await tester.pumpAndSettle();
expect(scrollController.offset, 100.0);
expect(scrollController.position.maxScrollExtent, 100.0);

});
}

0 comments on commit 1b8dc90

Please sign in to comment.