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.animation,
|
||||||
widget.route.secondaryAnimation,
|
widget.route.secondaryAnimation,
|
||||||
IgnorePointer(
|
IgnorePointer(
|
||||||
ignoring: widget.route.animation?.status == AnimationStatus.reverse,
|
ignoring: widget.route.navigator.userGestureInProgress
|
||||||
|
|| widget.route.animation?.status == AnimationStatus.reverse,
|
||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -347,7 +347,18 @@ void main() {
|
||||||
tester.getTopLeft(find.ancestor(of: find.text('route'), matching: find.byType(CupertinoPageScaffold))).dx,
|
tester.getTopLeft(find.ancestor(of: find.text('route'), matching: find.byType(CupertinoPageScaffold))).dx,
|
||||||
moreOrLessEquals(798, epsilon: 1),
|
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();
|
await tester.pumpAndSettle();
|
||||||
expect(find.text('route'), findsOneWidget);
|
expect(find.text('route'), findsOneWidget);
|
||||||
expect(find.text('push'), findsNothing);
|
expect(find.text('push'), findsNothing);
|
||||||
|
@ -816,6 +827,69 @@ void main() {
|
||||||
0x7A000000,
|
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 {}
|
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,
|
tester.getTopLeft(find.ancestor(of: find.text('route'), matching: find.byType(Scaffold))).dx,
|
||||||
moreOrLessEquals(798, epsilon: 1),
|
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();
|
await tester.pumpAndSettle();
|
||||||
expect(find.text('route'), findsOneWidget);
|
expect(find.text('route'), findsOneWidget);
|
||||||
expect(find.text('push'), findsNothing);
|
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