Skip to content

Commit 5a85c2d

Browse files
Merge branch 'master' into fix/pageController_get_value_error
* master: (23 commits) Roll pub packages (flutter#150810) Remove reference to `MaterialApp` and `showCupertinoModalPopup` from `CupertinoAlertDialog` (flutter#150725) Read `AndroidManifest.xml` and emit `manifest-impeller-(enabled|disabled)` analytics (flutter#150791) [flutter_tools] Shut down Chromium cleanly using a command sent through the debug protocol (flutter#150645) Reland fix inputDecorator hint color on M3 (flutter#150278) Roll Flutter Engine from 62e0b5f9c340 to 94023d711db3 (7 revisions) (flutter#150797) Fix collapsed InputDecorator minimum height (flutter#150770) Add more warm up frame docs (flutter#150464) Roll pub packages (flutter#150739) Add `focusNode`, `focusColor`, `onFocusChange`, `autofocus` to `CupertinoButton` (flutter#150721) Document RenderObject._relayoutBoundary and its invariant; small refactors (flutter#150527) Roll Flutter Engine from 6313b1e5afd7 to 62e0b5f9c340 (1 revision) (flutter#150790) fix a typo (flutter#150682) Fix link in RenderObjectWidget doc comment (flutter#150600) Roll Flutter Engine from fbd92055f3a6 to 6313b1e5afd7 (1 revision) (flutter#150781) [tool] make `ErrorHandlingFileSystem.deleteIfExists` catch error code 3 (`ERROR_PATH_NOT_FOUND` on Windows) (flutter#150741) Roll Packages from 711b4ac to 03f5f6d (21 revisions) (flutter#150779) Roll Flutter Engine from afa7ce19bca8 to fbd92055f3a6 (1 revision) (flutter#150777) Reland Add tests for form_text_field.1.dart (flutter#150481) (flutter#150696) (flutter#150750) Add an example for CupertinoPopupSurface (flutter#150357) ...
2 parents 993c6bd + 1a445b9 commit 5a85c2d

34 files changed

+1276
-304
lines changed

bin/internal/engine.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
be7db94196fee940e319363f7ed0c486a780ae50
1+
94023d711db3f950a235fd84a80a3dde4dd86338

bin/internal/flutter_packages.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
711b4ac2794e299e8d8926a269f672b1eba56640
1+
03f5f6d5660cf1dd77586d207845971ce2bebb93

bin/internal/fuchsia-linux.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
iU-B6rJxy0wUYSmmp1O7ykcFNnD26n1wW_i9UZ8fT4kC
1+
WUN7NQK04NjF9fRmfM16ILdIhytQAHB7O1631G4HsIEC

dev/bots/check_code_samples.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,6 @@ final Set<String> _knownMissingTests = <String>{
325325
'examples/api/test/material/flexible_space_bar/flexible_space_bar.0_test.dart',
326326
'examples/api/test/material/chip/deletable_chip_attributes.on_deleted.0_test.dart',
327327
'examples/api/test/material/expansion_panel/expansion_panel_list.expansion_panel_list_radio.0_test.dart',
328-
'examples/api/test/material/text_form_field/text_form_field.1_test.dart',
329328
'examples/api/test/material/scrollbar/scrollbar.1_test.dart',
330329
'examples/api/test/material/search_anchor/search_anchor.0_test.dart',
331330
'examples/api/test/material/search_anchor/search_anchor.1_test.dart',

dev/tools/gen_defaults/lib/input_decorator_template.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ class _${blockName}DefaultsM3 extends InputDecorationTheme {
3434
@override
3535
TextStyle? get hintStyle => MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
3636
if (states.contains(MaterialState.disabled)) {
37-
return TextStyle(color: Theme.of(context).disabledColor);
37+
return TextStyle(color: ${componentColor('md.comp.filled-text-field.disabled.supporting-text')});
3838
}
39-
return TextStyle(color: Theme.of(context).hintColor);
39+
return TextStyle(color: ${componentColor('md.comp.filled-text-field.supporting-text')});
4040
});
4141
4242
@override

docs/engine/Life-of-a-Flutter-Frame.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ Flutter does some minimal housekeeping when a frame is requested, primarily to i
1818

1919
Once a frame is scheduled, Flutter [waits for a vsync][vsyncWaiter] from the operating system to proceed.
2020

21-
2221
## Building the frame
2322

2423
At the heart of Flutter's graphics workflow is the frame [pipeline][pipeline]. The pipeline is responsible for coordinating work between the UI thread, where the application code runs, and the Raster thread, where rasterization and compositing is performed. See the [threading section][engineArchThreading] of the Engine Architecture wiki for more details on threading in the engine.
@@ -41,6 +40,28 @@ Once a surface is acquired, the [LayerTree][layerTree] is rasterized to the surf
4140

4241
The above process is repeated until the pipeline is empty.
4342

43+
## Warm-up frame
44+
45+
Normally, the Flutter framework begins producing a frame when it receives
46+
a vsync event from the operating system. However, this may not happen for
47+
several milliseconds after the app starts (or after a hot reload). To make
48+
use of the time between when the widget tree is first configured and when
49+
the engine requests an update, the framework schedules a _warm-up frame_
50+
using [PlatformDispatcher.scheduleWarmUpFrame][scheduleWarmUpFrame].
51+
52+
A warm-up frame may never actually render (as it invokes
53+
[FlutterView.render][flutterViewRender] outside of the scope of
54+
[PlatformDispatcher.onBeginFrame][onBeginFrame] or
55+
[PlatformDispatcher.onDrawFrame][onDrawFrame]), but it will cause the framework
56+
to go through the steps of building, laying out, and painting, which can
57+
together take several milliseconds. Thus, when the engine requests a real frame,
58+
much of the work will already have been completed, and the framework can
59+
generate the frame with minimal additional effort.
60+
61+
At startup, a warm-up frame can be produced before the Flutter engine has reported the
62+
initial view metrics using [PlatformDispatcher.onMetricsChanged][onMetricsChanged].
63+
As a result, the first frame can be produced with a size of zero.
64+
4465
## Cleaning up frame resources
4566

4667
TODO(cbracken): write this up using [this patch](https://github.com/flutter/engine/pull/38038) as a reminder.
@@ -53,10 +74,13 @@ TODO(cbracken): write this up using [this patch](https://github.com/flutter/engi
5374
[handleBeginFrame]: https://api.flutter.dev/flutter/scheduler/SchedulerBinding/handleBeginFrame.html
5475
[layerTree]: https://github.com/flutter/engine/blob/main/flow/layers/layer_tree.h
5576
[onBeginFrame]: https://api.flutter.dev/flutter/dart-ui/PlatformDispatcher/onBeginFrame.html
77+
[onDrawFrame]: https://api.flutter.dev/flutter/dart-ui/PlatformDispatcher/onDrawFrame.html
78+
[onMetricsChanged]: https://api.flutter.dev/flutter/dart-ui/PlatformDispatcher/onMetricsChanged.html
5679
[pipeline]: https://github.com/flutter/engine/blob/main/shell/common/pipeline.h
5780
[rasterizer]: https://github.com/flutter/engine/blob/main/shell/common/rasterizer.h
5881
[renderingPipelineTalk]: https://www.youtube.com/watch?v=UUfXWzp0-DU
5982
[scene]: https://api.flutter.dev/flutter/dart-ui/Scene-class.html
83+
[scheduleWarmUpFrame]: https://api.flutter.dev/flutter/dart-ui/PlatformDispatcher/scheduleWarmUpFrame.html
6084
[surface]: https://github.com/flutter/engine/blob/main/flow/surface.h
6185
[scheduleFrame]: https://api.flutter.dev/flutter/dart-ui/PlatformDispatcher/scheduleFrame.html
6286
[vsyncWaiter]: https://github.com/flutter/engine/blob/main/shell/common/vsync_waiter.h

examples/api/lib/cupertino/dialog/cupertino_alert_dialog.0.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@ class AlertDialogApp extends StatelessWidget {
2323
class AlertDialogExample extends StatelessWidget {
2424
const AlertDialogExample({super.key});
2525

26-
// This shows a CupertinoModalPopup which hosts a CupertinoAlertDialog.
2726
void _showAlertDialog(BuildContext context) {
28-
showCupertinoModalPopup<void>(
27+
showCupertinoDialog<void>(
2928
context: context,
3029
builder: (BuildContext context) => CupertinoAlertDialog(
3130
title: const Text('Alert'),
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/cupertino.dart';
6+
7+
/// Flutter code sample for [CupertinoPopupSurface].
8+
9+
void main() => runApp(const PopupSurfaceApp());
10+
11+
class PopupSurfaceApp extends StatelessWidget {
12+
const PopupSurfaceApp({super.key});
13+
14+
@override
15+
Widget build(BuildContext context) {
16+
return const CupertinoApp(
17+
home: PopupSurfaceExample(),
18+
);
19+
}
20+
}
21+
22+
class PopupSurfaceExample extends StatefulWidget {
23+
const PopupSurfaceExample({super.key});
24+
25+
@override
26+
State<PopupSurfaceExample> createState() => _PopupSurfaceExampleState();
27+
}
28+
29+
class _PopupSurfaceExampleState extends State<PopupSurfaceExample> {
30+
bool _shouldPaintSurface = true;
31+
32+
@override
33+
Widget build(BuildContext context) {
34+
return CupertinoPageScaffold(
35+
child: Center(
36+
child: Column(
37+
mainAxisAlignment: MainAxisAlignment.center,
38+
children: <Widget>[
39+
Row(
40+
mainAxisSize: MainAxisSize.min,
41+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
42+
children: <Widget>[
43+
const Text('Paint surface'),
44+
const SizedBox(width: 16.0),
45+
CupertinoSwitch(
46+
value: _shouldPaintSurface,
47+
onChanged: (bool value) => setState(() => _shouldPaintSurface = value),
48+
),
49+
],
50+
),
51+
CupertinoButton(
52+
onPressed: () => _showPopupSurface(context),
53+
child: const Text('Show popup'),
54+
),
55+
],
56+
),
57+
),
58+
);
59+
}
60+
61+
void _showPopupSurface(BuildContext context) {
62+
showCupertinoModalPopup<void>(
63+
context: context,
64+
builder: (BuildContext context) {
65+
return CupertinoPopupSurface(
66+
isSurfacePainted: _shouldPaintSurface,
67+
child: Container(
68+
height: 240,
69+
padding: const EdgeInsets.all(8.0),
70+
child: Column(
71+
children: <Widget>[
72+
Expanded(
73+
child: Container(
74+
alignment: Alignment.center,
75+
decoration: _shouldPaintSurface
76+
? null
77+
: BoxDecoration(
78+
color: CupertinoTheme.of(context).scaffoldBackgroundColor,
79+
borderRadius: BorderRadius.circular(8.0),
80+
),
81+
child: const Text('This is a popup surface.'),
82+
),
83+
),
84+
const SizedBox(height: 8.0),
85+
SizedBox(
86+
width: double.infinity,
87+
child: CupertinoButton(
88+
color: _shouldPaintSurface
89+
? null
90+
: CupertinoTheme.of(context).scaffoldBackgroundColor,
91+
onPressed: () => Navigator.pop(context),
92+
child: const Text(
93+
'Close',
94+
style: TextStyle(color: CupertinoColors.systemBlue),
95+
),
96+
),
97+
),
98+
],
99+
),
100+
),
101+
);
102+
},
103+
);
104+
}
105+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/cupertino.dart';
6+
import 'package:flutter_api_samples/cupertino/dialog/cupertino_popup_surface.0.dart'
7+
as example;
8+
import 'package:flutter_test/flutter_test.dart';
9+
10+
void main() {
11+
testWidgets('CupertinoPopupSurface displays expected widgets in init state',
12+
(WidgetTester tester) async {
13+
await tester.pumpWidget(const example.PopupSurfaceApp());
14+
15+
final Finder cupertinoButton = find.byType(CupertinoButton);
16+
expect(cupertinoButton, findsOneWidget);
17+
18+
final Finder cupertinoSwitch = find.byType(CupertinoSwitch);
19+
expect(cupertinoSwitch, findsOneWidget);
20+
});
21+
22+
testWidgets('CupertinoPopupSurface is displayed with painted surface',
23+
(WidgetTester tester) async {
24+
await tester.pumpWidget(const example.PopupSurfaceApp());
25+
26+
// CupertinoSwitch is toggled on by default.
27+
expect(tester.widget<CupertinoSwitch>(find.byType(CupertinoSwitch)).value, isTrue);
28+
29+
// Tap on the CupertinoButton to show the CupertinoPopupSurface.
30+
await tester.tap(find.byType(CupertinoButton));
31+
await tester.pumpAndSettle();
32+
33+
// Make sure CupertinoPopupSurface is showing.
34+
final Finder cupertinoPopupSurface = find.byType(CupertinoPopupSurface);
35+
expect(cupertinoPopupSurface, findsOneWidget);
36+
37+
// Confirm that CupertinoPopupSurface is painted with a ColoredBox.
38+
final Finder coloredBox = find.descendant(
39+
of: cupertinoPopupSurface,
40+
matching: find.byType(ColoredBox),
41+
);
42+
expect(coloredBox, findsOneWidget);
43+
});
44+
45+
testWidgets('CupertinoPopupSurface is displayed without painted surface',
46+
(WidgetTester tester) async {
47+
await tester.pumpWidget(const example.PopupSurfaceApp());
48+
49+
// Toggling off CupertinoSwitch and confirm its state.
50+
final Finder cupertinoSwitch = find.byType(CupertinoSwitch);
51+
await tester.tap(cupertinoSwitch);
52+
await tester.pumpAndSettle();
53+
expect(tester.widget<CupertinoSwitch>(cupertinoSwitch).value, isFalse);
54+
55+
// Tap on the CupertinoButton to show the CupertinoPopupSurface.
56+
await tester.tap(find.byType(CupertinoButton));
57+
await tester.pumpAndSettle();
58+
59+
// Make sure CupertinoPopupSurface is showing.
60+
final Finder cupertinoPopupSurface = find.byType(CupertinoPopupSurface);
61+
expect(cupertinoPopupSurface, findsOneWidget);
62+
63+
// Confirm that CupertinoPopupSurface is not painted with a ColoredBox.
64+
final Finder coloredBox = find.descendant(
65+
of: cupertinoPopupSurface,
66+
matching: find.byType(ColoredBox),
67+
);
68+
expect(coloredBox, findsNothing);
69+
});
70+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/material.dart';
6+
import 'package:flutter/services.dart';
7+
import 'package:flutter_api_samples/material/text_form_field/text_form_field.1.dart' as example;
8+
import 'package:flutter_test/flutter_test.dart';
9+
10+
void main() {
11+
testWidgets('Pressing space should focus the next field', (WidgetTester tester) async {
12+
await tester.pumpWidget(const example.TextFormFieldExampleApp());
13+
final Finder textFormField = find.byType(TextFormField);
14+
15+
expect(textFormField, findsExactly(5));
16+
17+
final Finder editableText = find.byType(EditableText);
18+
expect(editableText, findsExactly(5));
19+
20+
List<bool> getFocuses() {
21+
return editableText.evaluate()
22+
.map((Element finderResult) => (finderResult.widget as EditableText).focusNode.hasFocus)
23+
.toList();
24+
}
25+
26+
expect(getFocuses(), const <bool>[false, false, false, false, false]);
27+
28+
await tester.tap(textFormField.first);
29+
await tester.pump();
30+
31+
expect(getFocuses(), const <bool>[true, false, false, false, false]);
32+
33+
await tester.sendKeyEvent(LogicalKeyboardKey.space);
34+
await tester.pump();
35+
36+
expect(getFocuses(), const <bool>[false, true, false, false, false]);
37+
38+
await tester.sendKeyEvent(LogicalKeyboardKey.space);
39+
await tester.pump();
40+
41+
expect(getFocuses(), const <bool>[false, false, true, false, false]);
42+
43+
await tester.sendKeyEvent(LogicalKeyboardKey.space);
44+
await tester.pump();
45+
46+
expect(getFocuses(), const <bool>[false, false, false, true, false]);
47+
48+
await tester.sendKeyEvent(LogicalKeyboardKey.space);
49+
await tester.pump();
50+
51+
expect(getFocuses(), const <bool>[false, false, false, false, true]);
52+
53+
await tester.sendKeyEvent(LogicalKeyboardKey.space);
54+
await tester.pump();
55+
56+
expect(getFocuses(), const <bool>[true, false, false, false, false]);
57+
});
58+
}

0 commit comments

Comments
 (0)