@@ -31,6 +31,25 @@ void drawHelloWorld(ui.FlutterView view) {
31
31
view.render (sceneBuilder.build ());
32
32
}
33
33
34
+ Future <void > _waitUntilWindowVisible () async {
35
+ while (! await isWindowVisible ()) {
36
+ await Future <void >.delayed (const Duration (milliseconds: 100 ));
37
+ }
38
+ }
39
+
40
+ void _expectVisible (bool current, bool expect, Completer <String > completer, int frameCount) {
41
+ if (current != expect) {
42
+ try {
43
+ throw 'Window should be ${expect ? 'visible' : 'hidden' } on frame $frameCount ' ;
44
+ } catch (e) {
45
+ if (! completer.isCompleted) {
46
+ completer.completeError (e);
47
+ }
48
+ rethrow ;
49
+ }
50
+ }
51
+ }
52
+
34
53
void main () async {
35
54
// TODO(goderbauer): Create a window if embedder doesn't provide an implicit view to draw into.
36
55
assert (ui.PlatformDispatcher .instance.implicitView != null );
@@ -70,27 +89,39 @@ void main() async {
70
89
throw 'Window should be hidden at startup' ;
71
90
}
72
91
73
- bool firstFrame = true ;
74
- ui.PlatformDispatcher .instance.onBeginFrame = (Duration duration) async {
75
- if (await isWindowVisible ()) {
76
- if (firstFrame) {
77
- throw 'Window should be hidden on first frame' ;
78
- }
79
-
80
- if (! visibilityCompleter.isCompleted) {
81
- visibilityCompleter.complete ('success' );
82
- }
92
+ int frameCount = 0 ;
93
+ ui.PlatformDispatcher .instance.onBeginFrame = (Duration duration) {
94
+ // Our goal is to verify that it's `drawHelloWorld` that makes the window
95
+ // appear, not anything else. This requires checking the visibility right
96
+ // before drawing, but since `isWindowVisible` has to be async, and
97
+ // `FlutterView.render` (in `drawHelloWorld`) forbids async before it,
98
+ // this can not be done during a single onBeginFrame. However, we can
99
+ // verify in separate frames to indirectly prove it, by ensuring that
100
+ // no other mechanism can affect isWindowVisible in the first frame at all.
101
+ frameCount += 1 ;
102
+ switch (frameCount) {
103
+ // The 1st frame: render nothing, just verify that the window is hidden.
104
+ case 1 :
105
+ isWindowVisible ().then ((bool visible) {
106
+ _expectVisible (visible, false , visibilityCompleter, frameCount);
107
+ ui.PlatformDispatcher .instance.scheduleFrame ();
108
+ });
109
+ // The 2nd frame: render, which makes the window appear.
110
+ case 2 :
111
+ drawHelloWorld (view);
112
+ _waitUntilWindowVisible ().then ((_) {
113
+ if (! visibilityCompleter.isCompleted) {
114
+ visibilityCompleter.complete ('success' );
115
+ }
116
+ });
117
+ // Others, in case requested to render.
118
+ default :
119
+ drawHelloWorld (view);
83
120
}
84
-
85
- // Draw something to trigger the first frame callback that displays the
86
- // window.
87
- drawHelloWorld (view);
88
- firstFrame = false ;
89
121
};
90
-
91
- ui.PlatformDispatcher .instance.scheduleFrame ();
92
122
} catch (e) {
93
123
visibilityCompleter.completeError (e);
94
124
rethrow ;
95
125
}
126
+ ui.PlatformDispatcher .instance.scheduleFrame ();
96
127
}
0 commit comments