From e0e55dfbcba1a636145eaf21d63faef34b3c83a7 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 18 Oct 2022 14:01:31 -0700 Subject: [PATCH 01/11] [framework] re-rasterize when window size changes --- .../src/material/page_transitions_theme.dart | 24 ++++++++++++ packages/flutter/test/material/page_test.dart | 38 +++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/packages/flutter/lib/src/material/page_transitions_theme.dart b/packages/flutter/lib/src/material/page_transitions_theme.dart index bcc201c469cc9..88f868b66cbd8 100644 --- a/packages/flutter/lib/src/material/page_transitions_theme.dart +++ b/packages/flutter/lib/src/material/page_transitions_theme.dart @@ -291,6 +291,7 @@ class _ZoomEnterTransitionState extends State<_ZoomEnterTransition> with _ZoomTr bool get useSnapshot => !kIsWeb && widget.allowSnapshotting; late _ZoomEnterTransitionPainter delegate; + MediaQueryData? mediaQueryData; static final Animatable _fadeInTransition = Tween( begin: 0.0, @@ -354,6 +355,17 @@ class _ZoomEnterTransitionState extends State<_ZoomEnterTransition> with _ZoomTr } super.didUpdateWidget(oldWidget); } + + @override + void didChangeDependencies() { + // If the screen size changes during the transition, perhaps due to + // a keyboard dismissal, then ensure that contents are re-rasterized once. + final MediaQueryData data = MediaQuery.of(context); + if (mediaQueryData != null && data.size != mediaQueryData!.size) { + controller.clear(); + } + super.didChangeDependencies(); + } @override void dispose() { @@ -394,6 +406,7 @@ class _ZoomExitTransition extends StatefulWidget { class _ZoomExitTransitionState extends State<_ZoomExitTransition> with _ZoomTransitionBase { late _ZoomExitTransitionPainter delegate; + MediaQueryData? mediaQueryData; // See SnapshotWidget doc comment, this is disabled on web because the HTML backend doesn't // support this functionality and the canvaskit backend uses a single thread for UI and raster @@ -458,6 +471,17 @@ class _ZoomExitTransitionState extends State<_ZoomExitTransition> with _ZoomTran super.didUpdateWidget(oldWidget); } + @override + void didChangeDependencies() { + // If the screen size changes during the transition, perhaps due to + // a keyboard dismissal, then ensure that contents are re-rasterized once. + final MediaQueryData data = MediaQuery.of(context); + if (mediaQueryData != null && data.size != mediaQueryData!.size) { + controller.clear(); + } + super.didChangeDependencies(); + } + @override void dispose() { widget.animation.removeListener(onAnimationValueChange); diff --git a/packages/flutter/test/material/page_test.dart b/packages/flutter/test/material/page_test.dart index 7c6dc815b60a1..b891341ac9737 100644 --- a/packages/flutter/test/material/page_test.dart +++ b/packages/flutter/test/material/page_test.dart @@ -234,6 +234,44 @@ void main() { expect(find.text('Page 2'), findsNothing); }, variant: TargetPlatformVariant.only(TargetPlatform.android)); + testWidgets('test page transition (_ZoomPageTransition) with rasterization re-rasterizes when window size changes', (WidgetTester tester) async { + // Shrink the window size. + tester.binding.window.physicalSizeTestValue = const Size(100, 100); + + final Key key = GlobalKey(); + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: MaterialApp( + onGenerateRoute: (RouteSettings settings) { + return MaterialPageRoute( + builder: (BuildContext context) { + if (settings.name == '/') { + return const Material(child: Text('Page 1')); + } + return Material(child: Container(color: Colors.blue)); + }, + ); + }, + ), + ), + ); + + tester.state(find.byType(Navigator)).pushNamed('/next'); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 50)); + + await expectLater(find.byKey(key), matchesGoldenFile('zoom_page_transition.small.png')); + + // Increase the window size. + tester.binding.window.physicalSizeTestValue = const Size(400, 400); + + await tester.pump(); + await tester.pump(const Duration(milliseconds: 50)); + + await expectLater(find.byKey(key), matchesGoldenFile('zoom_page_transition.big.png')); + }, variant: TargetPlatformVariant.only(TargetPlatform.android)); + testWidgets('test fullscreen dialog transition', (WidgetTester tester) async { await tester.pumpWidget( const MaterialApp( From 8d3e9f017477b57f757a07261545b7bc0b691454 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 18 Oct 2022 14:20:38 -0700 Subject: [PATCH 02/11] ++ --- packages/flutter/lib/src/material/page_transitions_theme.dart | 2 +- packages/flutter/test/material/page_test.dart | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/flutter/lib/src/material/page_transitions_theme.dart b/packages/flutter/lib/src/material/page_transitions_theme.dart index 88f868b66cbd8..2522385a45176 100644 --- a/packages/flutter/lib/src/material/page_transitions_theme.dart +++ b/packages/flutter/lib/src/material/page_transitions_theme.dart @@ -355,7 +355,7 @@ class _ZoomEnterTransitionState extends State<_ZoomEnterTransition> with _ZoomTr } super.didUpdateWidget(oldWidget); } - + @override void didChangeDependencies() { // If the screen size changes during the transition, perhaps due to diff --git a/packages/flutter/test/material/page_test.dart b/packages/flutter/test/material/page_test.dart index b891341ac9737..3abc3afc484bc 100644 --- a/packages/flutter/test/material/page_test.dart +++ b/packages/flutter/test/material/page_test.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +@Tags(['reduced-test-set']) import 'package:flutter/cupertino.dart' show CupertinoPageRoute; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; @@ -237,7 +238,7 @@ void main() { testWidgets('test page transition (_ZoomPageTransition) with rasterization re-rasterizes when window size changes', (WidgetTester tester) async { // Shrink the window size. tester.binding.window.physicalSizeTestValue = const Size(100, 100); - + final Key key = GlobalKey(); await tester.pumpWidget( RepaintBoundary( From 5a8f79a0ec5d596c59501b70c262808355f50b86 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 18 Oct 2022 14:47:07 -0700 Subject: [PATCH 03/11] ++ --- .../lib/src/material/page_transitions_theme.dart | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/flutter/lib/src/material/page_transitions_theme.dart b/packages/flutter/lib/src/material/page_transitions_theme.dart index 2522385a45176..a691c0e2b2767 100644 --- a/packages/flutter/lib/src/material/page_transitions_theme.dart +++ b/packages/flutter/lib/src/material/page_transitions_theme.dart @@ -360,10 +360,11 @@ class _ZoomEnterTransitionState extends State<_ZoomEnterTransition> with _ZoomTr void didChangeDependencies() { // If the screen size changes during the transition, perhaps due to // a keyboard dismissal, then ensure that contents are re-rasterized once. - final MediaQueryData data = MediaQuery.of(context); - if (mediaQueryData != null && data.size != mediaQueryData!.size) { + final MediaQueryData? data = MediaQuery.maybeOf(context); + if (mediaQueryData?.size != data?.size) { controller.clear(); } + mediaQueryData = data; super.didChangeDependencies(); } @@ -475,10 +476,11 @@ class _ZoomExitTransitionState extends State<_ZoomExitTransition> with _ZoomTran void didChangeDependencies() { // If the screen size changes during the transition, perhaps due to // a keyboard dismissal, then ensure that contents are re-rasterized once. - final MediaQueryData data = MediaQuery.of(context); - if (mediaQueryData != null && data.size != mediaQueryData!.size) { + final MediaQueryData? data = MediaQuery.maybeOf(context); + if (mediaQueryData?.size != data?.size) { controller.clear(); } + mediaQueryData = data; super.didChangeDependencies(); } From 6653526e5c893439b5dc0dece04e89b47359c285 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Tue, 18 Oct 2022 15:06:51 -0700 Subject: [PATCH 04/11] Update page_test.dart --- packages/flutter/test/material/page_test.dart | 58 ++++++++++--------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/packages/flutter/test/material/page_test.dart b/packages/flutter/test/material/page_test.dart index 3abc3afc484bc..b74aa14e600b3 100644 --- a/packages/flutter/test/material/page_test.dart +++ b/packages/flutter/test/material/page_test.dart @@ -237,40 +237,44 @@ void main() { testWidgets('test page transition (_ZoomPageTransition) with rasterization re-rasterizes when window size changes', (WidgetTester tester) async { // Shrink the window size. - tester.binding.window.physicalSizeTestValue = const Size(100, 100); + try { + tester.binding.window.physicalSizeTestValue = const Size(100, 100); - final Key key = GlobalKey(); - await tester.pumpWidget( - RepaintBoundary( - key: key, - child: MaterialApp( - onGenerateRoute: (RouteSettings settings) { - return MaterialPageRoute( - builder: (BuildContext context) { - if (settings.name == '/') { - return const Material(child: Text('Page 1')); - } - return Material(child: Container(color: Colors.blue)); - }, - ); - }, + final Key key = GlobalKey(); + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: MaterialApp( + onGenerateRoute: (RouteSettings settings) { + return MaterialPageRoute( + builder: (BuildContext context) { + if (settings.name == '/') { + return const Material(child: Text('Page 1')); + } + return Material(child: Container(color: Colors.blue)); + }, + ); + }, + ), ), - ), - ); + ); - tester.state(find.byType(Navigator)).pushNamed('/next'); - await tester.pump(); - await tester.pump(const Duration(milliseconds: 50)); + tester.state(find.byType(Navigator)).pushNamed('/next'); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 50)); - await expectLater(find.byKey(key), matchesGoldenFile('zoom_page_transition.small.png')); + await expectLater(find.byKey(key), matchesGoldenFile('zoom_page_transition.small.png')); - // Increase the window size. - tester.binding.window.physicalSizeTestValue = const Size(400, 400); + // Increase the window size. + tester.binding.window.physicalSizeTestValue = const Size(400, 400); - await tester.pump(); - await tester.pump(const Duration(milliseconds: 50)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 50)); - await expectLater(find.byKey(key), matchesGoldenFile('zoom_page_transition.big.png')); + await expectLater(find.byKey(key), matchesGoldenFile('zoom_page_transition.big.png')); + } finally { + tester.binding.window.physicalSizeTestValue = null; + } }, variant: TargetPlatformVariant.only(TargetPlatform.android)); testWidgets('test fullscreen dialog transition', (WidgetTester tester) async { From 4feaf46a58f78fccfa3740d5f4a496346c3d675d Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Tue, 18 Oct 2022 18:01:32 -0700 Subject: [PATCH 05/11] Update page_test.dart --- packages/flutter/test/material/page_test.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/flutter/test/material/page_test.dart b/packages/flutter/test/material/page_test.dart index b74aa14e600b3..0055ebc14d7d5 100644 --- a/packages/flutter/test/material/page_test.dart +++ b/packages/flutter/test/material/page_test.dart @@ -237,7 +237,9 @@ void main() { testWidgets('test page transition (_ZoomPageTransition) with rasterization re-rasterizes when window size changes', (WidgetTester tester) async { // Shrink the window size. + late Size oldSize; try { + oldSize = tester.binding.window.physicalSize; tester.binding.window.physicalSizeTestValue = const Size(100, 100); final Key key = GlobalKey(); @@ -273,7 +275,7 @@ void main() { await expectLater(find.byKey(key), matchesGoldenFile('zoom_page_transition.big.png')); } finally { - tester.binding.window.physicalSizeTestValue = null; + tester.binding.window.physicalSizeTestValue = oldSize; } }, variant: TargetPlatformVariant.only(TargetPlatform.android)); From a2c7fcccce2cac7c17b24a64836f5440d35dcfcd Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Tue, 18 Oct 2022 18:44:01 -0700 Subject: [PATCH 06/11] Update page_test.dart --- packages/flutter/test/material/page_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/flutter/test/material/page_test.dart b/packages/flutter/test/material/page_test.dart index 0055ebc14d7d5..903acc7a35902 100644 --- a/packages/flutter/test/material/page_test.dart +++ b/packages/flutter/test/material/page_test.dart @@ -240,7 +240,7 @@ void main() { late Size oldSize; try { oldSize = tester.binding.window.physicalSize; - tester.binding.window.physicalSizeTestValue = const Size(100, 100); + tester.binding.window.physicalSizeTestValue = const Size(1000, 1000); final Key key = GlobalKey(); await tester.pumpWidget( @@ -268,7 +268,7 @@ void main() { await expectLater(find.byKey(key), matchesGoldenFile('zoom_page_transition.small.png')); // Increase the window size. - tester.binding.window.physicalSizeTestValue = const Size(400, 400); + tester.binding.window.physicalSizeTestValue = const Size(1000, 2000); await tester.pump(); await tester.pump(const Duration(milliseconds: 50)); From 1f8b93524355f679afb20e156a47da46759adaa1 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Tue, 18 Oct 2022 19:43:22 -0700 Subject: [PATCH 07/11] Update page_test.dart --- packages/flutter/test/material/page_test.dart | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/flutter/test/material/page_test.dart b/packages/flutter/test/material/page_test.dart index 903acc7a35902..82a54e6dc6acc 100644 --- a/packages/flutter/test/material/page_test.dart +++ b/packages/flutter/test/material/page_test.dart @@ -250,10 +250,7 @@ void main() { onGenerateRoute: (RouteSettings settings) { return MaterialPageRoute( builder: (BuildContext context) { - if (settings.name == '/') { - return const Material(child: Text('Page 1')); - } - return Material(child: Container(color: Colors.blue)); + return const Material(child: SizedBox.shrink()); }, ); }, From 0071be255c6a7976c21d76b495aa598279d9eb62 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 19 Oct 2022 11:08:21 -0700 Subject: [PATCH 08/11] Update page_test.dart --- packages/flutter/test/material/page_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/flutter/test/material/page_test.dart b/packages/flutter/test/material/page_test.dart index 82a54e6dc6acc..31294b618e587 100644 --- a/packages/flutter/test/material/page_test.dart +++ b/packages/flutter/test/material/page_test.dart @@ -233,7 +233,7 @@ void main() { expect(find.text('Page 1'), isOnstage); expect(find.text('Page 2'), findsNothing); - }, variant: TargetPlatformVariant.only(TargetPlatform.android)); + }, variant: TargetPlatformVariant.only(TargetPlatform.android), skip: kIsWeb); // [intended] rasterization is not used on the web. testWidgets('test page transition (_ZoomPageTransition) with rasterization re-rasterizes when window size changes', (WidgetTester tester) async { // Shrink the window size. From b9663e670a0734b0e5c8c813c8bde11804191850 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 19 Oct 2022 11:13:11 -0700 Subject: [PATCH 09/11] Update page_test.dart --- packages/flutter/test/material/page_test.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/flutter/test/material/page_test.dart b/packages/flutter/test/material/page_test.dart index 31294b618e587..d9d67bda1f301 100644 --- a/packages/flutter/test/material/page_test.dart +++ b/packages/flutter/test/material/page_test.dart @@ -4,6 +4,7 @@ @Tags(['reduced-test-set']) import 'package:flutter/cupertino.dart' show CupertinoPageRoute; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; From 998a5ce2e0948f037483811705e540a322fd97d7 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 19 Oct 2022 11:48:24 -0700 Subject: [PATCH 10/11] Update page_test.dart --- packages/flutter/test/material/page_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/flutter/test/material/page_test.dart b/packages/flutter/test/material/page_test.dart index d9d67bda1f301..b97bfd87c7308 100644 --- a/packages/flutter/test/material/page_test.dart +++ b/packages/flutter/test/material/page_test.dart @@ -234,7 +234,7 @@ void main() { expect(find.text('Page 1'), isOnstage); expect(find.text('Page 2'), findsNothing); - }, variant: TargetPlatformVariant.only(TargetPlatform.android), skip: kIsWeb); // [intended] rasterization is not used on the web. + }, variant: TargetPlatformVariant.only(TargetPlatform.android)); testWidgets('test page transition (_ZoomPageTransition) with rasterization re-rasterizes when window size changes', (WidgetTester tester) async { // Shrink the window size. @@ -275,7 +275,7 @@ void main() { } finally { tester.binding.window.physicalSizeTestValue = oldSize; } - }, variant: TargetPlatformVariant.only(TargetPlatform.android)); + }, variant: TargetPlatformVariant.only(TargetPlatform.android), skip: kIsWeb); // [intended] rasterization is not used on the web. testWidgets('test fullscreen dialog transition', (WidgetTester tester) async { await tester.pumpWidget( From 7d48ff19d77bf9a4813a45186c847bf3ab6ec1ef Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Mon, 24 Oct 2022 09:35:02 -0700 Subject: [PATCH 11/11] view insets --- .../lib/src/material/page_transitions_theme.dart | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/flutter/lib/src/material/page_transitions_theme.dart b/packages/flutter/lib/src/material/page_transitions_theme.dart index a691c0e2b2767..c2ff2098acbe7 100644 --- a/packages/flutter/lib/src/material/page_transitions_theme.dart +++ b/packages/flutter/lib/src/material/page_transitions_theme.dart @@ -361,7 +361,7 @@ class _ZoomEnterTransitionState extends State<_ZoomEnterTransition> with _ZoomTr // If the screen size changes during the transition, perhaps due to // a keyboard dismissal, then ensure that contents are re-rasterized once. final MediaQueryData? data = MediaQuery.maybeOf(context); - if (mediaQueryData?.size != data?.size) { + if (mediaQueryDataChanged(mediaQueryData, data)) { controller.clear(); } mediaQueryData = data; @@ -477,7 +477,7 @@ class _ZoomExitTransitionState extends State<_ZoomExitTransition> with _ZoomTran // If the screen size changes during the transition, perhaps due to // a keyboard dismissal, then ensure that contents are re-rasterized once. final MediaQueryData? data = MediaQuery.maybeOf(context); - if (mediaQueryData?.size != data?.size) { + if (mediaQueryDataChanged(mediaQueryData, data)) { controller.clear(); } mediaQueryData = data; @@ -830,6 +830,13 @@ mixin _ZoomTransitionBase { break; } } + + // Whether any of the properties that would impact the page transition + // changed. + bool mediaQueryDataChanged(MediaQueryData? oldData, MediaQueryData? newData) { + return oldData?.size != newData?.size || + oldData?.viewInsets != newData?.viewInsets; + } } class _ZoomEnterTransitionPainter extends SnapshotPainter {