mirror of
https://github.com/flutter/flutter
synced 2024-10-13 11:42:54 +00:00
ModalRoutes ignore input when a (cupertino) pop transition is underway (#40466)
This commit is contained in:
parent
25ac81ffdf
commit
0f00f424fa
|
@ -654,7 +654,8 @@ class _ModalScopeState<T> extends State<_ModalScope<T>> {
|
|||
widget.route.animation,
|
||||
widget.route.secondaryAnimation,
|
||||
IgnorePointer(
|
||||
ignoring: widget.route.animation?.status == AnimationStatus.reverse,
|
||||
ignoring: widget.route.navigator.userGestureInProgress
|
||||
|| widget.route.animation?.status == AnimationStatus.reverse,
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
|
|
|
@ -347,7 +347,18 @@ void main() {
|
|||
tester.getTopLeft(find.ancestor(of: find.text('route'), matching: find.byType(CupertinoPageScaffold))).dx,
|
||||
moreOrLessEquals(798, epsilon: 1),
|
||||
);
|
||||
await tester.tap(find.text('push'));
|
||||
|
||||
// Use the navigator to push a route instead of tapping the 'push' button.
|
||||
// The topmost route (the one that's animating away), ignores input while
|
||||
// the pop is underway because route.navigator.userGestureInProgress.
|
||||
Navigator.push<void>(scaffoldKey.currentContext, CupertinoPageRoute<void>(
|
||||
builder: (BuildContext context) {
|
||||
return const CupertinoPageScaffold(
|
||||
child: Center(child: Text('route')),
|
||||
);
|
||||
},
|
||||
));
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('route'), findsOneWidget);
|
||||
expect(find.text('push'), findsNothing);
|
||||
|
@ -816,6 +827,69 @@ void main() {
|
|||
0x7A000000,
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('During back swipe the route ignores input', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/39989
|
||||
|
||||
final GlobalKey homeScaffoldKey = GlobalKey();
|
||||
final GlobalKey pageScaffoldKey = GlobalKey();
|
||||
int homeTapCount = 0;
|
||||
int pageTapCount = 0;
|
||||
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
home: CupertinoPageScaffold(
|
||||
key: homeScaffoldKey,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
homeTapCount += 1;
|
||||
}
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.byKey(homeScaffoldKey));
|
||||
expect(homeTapCount, 1);
|
||||
expect(pageTapCount, 0);
|
||||
|
||||
Navigator.push<void>(homeScaffoldKey.currentContext, CupertinoPageRoute<void>(
|
||||
builder: (BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
key: pageScaffoldKey,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
pageTapCount += 1;
|
||||
}
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
));
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byKey(pageScaffoldKey));
|
||||
expect(homeTapCount, 1);
|
||||
expect(pageTapCount, 1);
|
||||
|
||||
// Start the basic iOS back-swipe dismiss transition. Drag the pushed
|
||||
// "page" route halfway across the screen. The underlying "home" will
|
||||
// start sliding in from the left.
|
||||
|
||||
final TestGesture gesture = await tester.startGesture(const Offset(5, 300));
|
||||
await gesture.moveBy(const Offset(400, 0));
|
||||
await tester.pump();
|
||||
expect(tester.getTopLeft(find.byKey(pageScaffoldKey)), const Offset(400, 0));
|
||||
expect(tester.getTopLeft(find.byKey(homeScaffoldKey)).dx, lessThan(0));
|
||||
|
||||
// Tapping on the "page" route doesn't trigger the GestureDetector because
|
||||
// it's being dragged.
|
||||
await tester.tap(find.byKey(pageScaffoldKey));
|
||||
expect(homeTapCount, 1);
|
||||
expect(pageTapCount, 1);
|
||||
});
|
||||
}
|
||||
|
||||
class MockNavigatorObserver extends Mock implements NavigatorObserver {}
|
||||
|
|
|
@ -620,9 +620,91 @@ void main() {
|
|||
tester.getTopLeft(find.ancestor(of: find.text('route'), matching: find.byType(Scaffold))).dx,
|
||||
moreOrLessEquals(798, epsilon: 1),
|
||||
);
|
||||
await tester.tap(find.text('push'));
|
||||
|
||||
// Use the navigator to push a route instead of tapping the 'push' button.
|
||||
// The topmost route (the one that's animating away), ignores input while
|
||||
// the pop is underway because route.navigator.userGestureInProgress.
|
||||
Navigator.push<void>(scaffoldKey.currentContext, MaterialPageRoute<void>(
|
||||
builder: (BuildContext context) {
|
||||
return const Scaffold(
|
||||
body: Center(child: Text('route')),
|
||||
);
|
||||
},
|
||||
));
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('route'), findsOneWidget);
|
||||
expect(find.text('push'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('During back swipe the route ignores input', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/39989
|
||||
|
||||
final GlobalKey homeScaffoldKey = GlobalKey();
|
||||
final GlobalKey pageScaffoldKey = GlobalKey();
|
||||
int homeTapCount = 0;
|
||||
int pageTapCount = 0;
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeData(platform: TargetPlatform.iOS),
|
||||
home: Scaffold(
|
||||
key: homeScaffoldKey,
|
||||
body: GestureDetector(
|
||||
onTap: () {
|
||||
homeTapCount += 1;
|
||||
}
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.byKey(homeScaffoldKey));
|
||||
expect(homeTapCount, 1);
|
||||
expect(pageTapCount, 0);
|
||||
|
||||
Navigator.push<void>(homeScaffoldKey.currentContext, MaterialPageRoute<void>(
|
||||
builder: (BuildContext context) {
|
||||
return Scaffold(
|
||||
key: pageScaffoldKey,
|
||||
appBar: AppBar(title: const Text('Page')),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
pageTapCount += 1;
|
||||
}
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
));
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byKey(pageScaffoldKey));
|
||||
expect(homeTapCount, 1);
|
||||
expect(pageTapCount, 1);
|
||||
|
||||
// Start the basic iOS back-swipe dismiss transition. Drag the pushed
|
||||
// "page" route halfway across the screen. The underlying "home" will
|
||||
// start sliding in from the left.
|
||||
|
||||
final TestGesture gesture = await tester.startGesture(const Offset(5, 300));
|
||||
await gesture.moveBy(const Offset(400, 0));
|
||||
await tester.pump();
|
||||
expect(tester.getTopLeft(find.byKey(pageScaffoldKey)), const Offset(400, 0));
|
||||
expect(tester.getTopLeft(find.byKey(homeScaffoldKey)).dx, lessThan(0));
|
||||
|
||||
// Tapping on the "page" route doesn't trigger the GestureDetector because
|
||||
// it's being dragged.
|
||||
await tester.tap(find.byKey(pageScaffoldKey));
|
||||
expect(homeTapCount, 1);
|
||||
expect(pageTapCount, 1);
|
||||
|
||||
// Tapping the "page" route's back button doesn't do anything either.
|
||||
await tester.tap(find.byTooltip('Back'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(tester.getTopLeft(find.byKey(pageScaffoldKey)), const Offset(400, 0));
|
||||
expect(tester.getTopLeft(find.byKey(homeScaffoldKey)).dx, lessThan(0));
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue