@@ -48,12 +48,8 @@ impl Plugin for WinitPlugin {
48
48
#[ cfg( target_arch = "wasm32" ) ]
49
49
app. add_plugin ( web_resize:: CanvasParentResizePlugin ) ;
50
50
let event_loop = EventLoop :: new ( ) ;
51
- let mut create_window_reader = WinitCreateWindowReader :: default ( ) ;
52
- // Note that we create a window here "early" because WASM/WebGL requires the window to exist prior to initializing
53
- // the renderer.
54
- handle_create_window_events ( & mut app. world , & event_loop, & mut create_window_reader. 0 ) ;
55
- app. insert_resource ( create_window_reader)
56
- . insert_non_send_resource ( event_loop) ;
51
+
52
+ app. insert_non_send_resource ( event_loop) ;
57
53
}
58
54
}
59
55
@@ -256,6 +252,8 @@ pub fn winit_runner(app: App) {
256
252
257
253
/// Stores state that must persist between frames.
258
254
struct WinitPersistentState {
255
+ /// Tracks whether the application has reached its first `Resumed` event
256
+ reached_first_resume : bool ,
259
257
/// Tracks whether or not the application is active or suspended.
260
258
active : bool ,
261
259
/// Tracks whether or not an event has occurred this frame that would trigger an update in low
@@ -270,7 +268,14 @@ struct WinitPersistentState {
270
268
impl Default for WinitPersistentState {
271
269
fn default ( ) -> Self {
272
270
Self {
273
- active : true ,
271
+ reached_first_resume : false ,
272
+
273
+ // We have to start non-active and block update()s until we get our
274
+ // first 'Resumed' event where we will first check for any CreateWindow requests.
275
+ // If we don't block updates then the Events::update system will clear the requests
276
+ // before they are handled!
277
+ active : false ,
278
+
274
279
low_power_event : false ,
275
280
redraw_request_sent : false ,
276
281
timeout_reached : false ,
@@ -279,20 +284,12 @@ impl Default for WinitPersistentState {
279
284
}
280
285
}
281
286
282
- #[ derive( Default ) ]
283
- struct WinitCreateWindowReader ( ManualEventReader < CreateWindow > ) ;
284
-
285
287
pub fn winit_runner_with ( mut app : App ) {
286
- app. render_init ( ) ;
287
288
let mut event_loop = app
288
289
. world
289
290
. remove_non_send_resource :: < EventLoop < ( ) > > ( )
290
291
. unwrap ( ) ;
291
- let mut create_window_event_reader = app
292
- . world
293
- . remove_resource :: < WinitCreateWindowReader > ( )
294
- . unwrap ( )
295
- . 0 ;
292
+ let mut create_window_event_reader = ManualEventReader :: < CreateWindow > :: default ( ) ;
296
293
let mut app_exit_event_reader = ManualEventReader :: < AppExit > :: default ( ) ;
297
294
let mut redraw_event_reader = ManualEventReader :: < RequestRedraw > :: default ( ) ;
298
295
let mut winit_state = WinitPersistentState :: default ( ) ;
@@ -307,6 +304,32 @@ pub fn winit_runner_with(mut app: App) {
307
304
event_loop : & EventLoopWindowTarget < ( ) > ,
308
305
control_flow : & mut ControlFlow | {
309
306
match event {
307
+ // Ideally Winit would emit `Resumed` events consistently for all platforms but for
308
+ // now we treat NewEvents(Init) the same as a Resumed event for all platforms except
309
+ // Android
310
+ event:: Event :: Resumed | event:: Event :: NewEvents ( StartCause :: Init ) => {
311
+ if cfg ! ( not( target_os = "android" ) ) || matches ! ( event, event:: Event :: Resumed ) {
312
+ winit_state. active = true ;
313
+
314
+ if !winit_state. reached_first_resume {
315
+ // Create any primary winit window that's been requested before we initialize
316
+ // render state. This ensures it's possible to create a surface for the
317
+ // window that can in turn be used to find a compatible adapter.
318
+ //
319
+ // In particular this is required for webgl
320
+ handle_create_window_events (
321
+ & mut app. world ,
322
+ event_loop,
323
+ & mut create_window_event_reader,
324
+ ) ;
325
+ app. render_init ( ) ;
326
+ winit_state. reached_first_resume = true ;
327
+ }
328
+ }
329
+ }
330
+ event:: Event :: Suspended => {
331
+ winit_state. active = false ;
332
+ }
310
333
event:: Event :: NewEvents ( start) => {
311
334
let winit_config = app. world . resource :: < WinitSettings > ( ) ;
312
335
let windows = app. world . resource :: < Windows > ( ) ;
@@ -550,18 +573,17 @@ pub fn winit_runner_with(mut app: App) {
550
573
delta : Vec2 :: new ( delta. 0 as f32 , delta. 1 as f32 ) ,
551
574
} ) ;
552
575
}
553
- event:: Event :: Suspended => {
554
- winit_state. active = false ;
555
- }
556
- event:: Event :: Resumed => {
557
- winit_state. active = true ;
558
- }
559
576
event:: Event :: MainEventsCleared => {
560
- handle_create_window_events (
561
- & mut app. world ,
562
- event_loop,
563
- & mut create_window_event_reader,
564
- ) ;
577
+ // We only initialize render state and start creating any
578
+ // windows once the app has has 'resumed' for the first time.
579
+ if winit_state. reached_first_resume {
580
+ handle_create_window_events (
581
+ & mut app. world ,
582
+ event_loop,
583
+ & mut create_window_event_reader,
584
+ ) ;
585
+ }
586
+
565
587
let winit_config = app. world . resource :: < WinitSettings > ( ) ;
566
588
let update = if winit_state. active {
567
589
let windows = app. world . resource :: < Windows > ( ) ;
0 commit comments