@@ -254,6 +254,8 @@ struct WinitAppRunnerState {
254
254
active : ActiveState ,
255
255
/// Is `true` if a new [`WindowEvent`] has been received since the last update.
256
256
window_event_received : bool ,
257
+ /// Is `true` if a new [`DeviceEvent`] has been received since the last update.
258
+ device_event_received : bool ,
257
259
/// Is `true` if the app has requested a redraw since the last update.
258
260
redraw_requested : bool ,
259
261
/// Is `true` if enough time has elapsed since `last_update` to run another update.
@@ -262,6 +264,17 @@ struct WinitAppRunnerState {
262
264
last_update : Instant ,
263
265
/// The time the next update is scheduled to start.
264
266
scheduled_update : Option < Instant > ,
267
+ /// Number of "forced" updates to trigger on application start
268
+ startup_forced_updates : u32 ,
269
+ }
270
+
271
+ impl WinitAppRunnerState {
272
+ fn reset_on_update ( & mut self ) {
273
+ self . redraw_requested = false ;
274
+ self . window_event_received = false ;
275
+ self . device_event_received = false ;
276
+ self . wait_elapsed = false ;
277
+ }
265
278
}
266
279
267
280
#[ derive( PartialEq , Eq ) ]
@@ -287,10 +300,13 @@ impl Default for WinitAppRunnerState {
287
300
Self {
288
301
active : ActiveState :: NotYetStarted ,
289
302
window_event_received : false ,
303
+ device_event_received : false ,
290
304
redraw_requested : false ,
291
305
wait_elapsed : false ,
292
306
last_update : Instant :: now ( ) ,
293
307
scheduled_update : None ,
308
+ // 3 seems to be enough, 5 is a safe margin
309
+ startup_forced_updates : 5 ,
294
310
}
295
311
}
296
312
}
@@ -364,14 +380,56 @@ pub fn winit_runner(mut app: App) {
364
380
365
381
match event {
366
382
Event :: AboutToWait => {
367
- if runner_state. redraw_requested {
383
+ let ( config, windows) = focused_windows_state. get ( & app. world ) ;
384
+ let focused = windows. iter ( ) . any ( |window| window. focused ) ;
385
+ let mut should_update = match config. update_mode ( focused) {
386
+ UpdateMode :: Continuous => {
387
+ runner_state. redraw_requested
388
+ || runner_state. window_event_received
389
+ || runner_state. device_event_received
390
+ }
391
+ UpdateMode :: Reactive { .. } => {
392
+ runner_state. wait_elapsed
393
+ || runner_state. redraw_requested
394
+ || runner_state. window_event_received
395
+ || runner_state. device_event_received
396
+ }
397
+ UpdateMode :: ReactiveLowPower { .. } => {
398
+ runner_state. wait_elapsed
399
+ || runner_state. redraw_requested
400
+ || runner_state. window_event_received
401
+ }
402
+ } ;
403
+
404
+ // Ensure that an update is triggered on the first iterations for app initialization
405
+ if runner_state. startup_forced_updates > 0 {
406
+ runner_state. startup_forced_updates -= 1 ;
407
+ should_update = true ;
408
+ }
409
+
410
+ if should_update {
411
+ let visible = windows. iter ( ) . any ( |window| window. visible ) ;
368
412
let ( _, winit_windows, _, _) =
369
413
event_writer_system_state. get_mut ( & mut app. world ) ;
370
- for window in winit_windows. windows . values ( ) {
371
- window. request_redraw ( ) ;
414
+ if visible {
415
+ for window in winit_windows. windows . values ( ) {
416
+ window. request_redraw ( ) ;
417
+ }
418
+ } else {
419
+ // there are no windows, or they are not visible.
420
+ // Winit won't send events on some platforms, so trigger an update manually.
421
+ run_app_update_if_should (
422
+ & mut runner_state,
423
+ & mut app,
424
+ & mut focused_windows_state,
425
+ event_loop,
426
+ & mut create_window_system_state,
427
+ & mut app_exit_event_reader,
428
+ & mut redraw_event_reader,
429
+ ) ;
430
+ event_loop. set_control_flow ( ControlFlow :: Poll ) ;
372
431
}
373
432
}
374
- runner_state. redraw_requested = false ;
375
433
}
376
434
Event :: NewEvents ( _) => {
377
435
if let Some ( t) = runner_state. scheduled_update {
@@ -638,7 +696,6 @@ pub fn winit_runner(mut app: App) {
638
696
} ) ;
639
697
}
640
698
WindowEvent :: RedrawRequested => {
641
- runner_state. redraw_requested = false ;
642
699
run_app_update_if_should (
643
700
& mut runner_state,
644
701
& mut app,
@@ -659,14 +716,14 @@ pub fn winit_runner(mut app: App) {
659
716
}
660
717
}
661
718
}
662
- Event :: DeviceEvent {
663
- event : DeviceEvent :: MouseMotion { delta : ( x , y ) } ,
664
- ..
665
- } => {
666
- let ( mut event_writers , .. ) = event_writer_system_state . get_mut ( & mut app . world ) ;
667
- event_writers . mouse_motion . send ( MouseMotion {
668
- delta : Vec2 :: new ( x as f32 , y as f32 ) ,
669
- } ) ;
719
+ Event :: DeviceEvent { event , .. } => {
720
+ runner_state . device_event_received = true ;
721
+ if let DeviceEvent :: MouseMotion { delta : ( x , y ) } = event {
722
+ let ( mut event_writers , .. ) = event_writer_system_state . get_mut ( & mut app . world ) ;
723
+ event_writers . mouse_motion . send ( MouseMotion {
724
+ delta : Vec2 :: new ( x as f32 , y as f32 ) ,
725
+ } ) ;
726
+ }
670
727
}
671
728
Event :: Suspended => {
672
729
let ( mut event_writers, ..) = event_writer_system_state. get_mut ( & mut app. world ) ;
@@ -700,7 +757,7 @@ pub fn winit_runner(mut app: App) {
700
757
) = create_window_system_state. get_mut ( & mut app. world ) ;
701
758
702
759
create_windows (
703
- & event_loop,
760
+ event_loop,
704
761
commands,
705
762
windows. iter_mut ( ) ,
706
763
event_writer,
@@ -793,6 +850,8 @@ fn run_app_update_if_should(
793
850
app_exit_event_reader : & mut ManualEventReader < AppExit > ,
794
851
redraw_event_reader : & mut ManualEventReader < RequestRedraw > ,
795
852
) {
853
+ runner_state. reset_on_update ( ) ;
854
+
796
855
if !runner_state. active . should_run ( ) {
797
856
return ;
798
857
}
@@ -808,32 +867,15 @@ fn run_app_update_if_should(
808
867
event_loop. set_control_flow ( ControlFlow :: Wait ) ;
809
868
}
810
869
}
811
- let ( config, windows) = focused_windows_state. get ( & app. world ) ;
812
- let focused = windows. iter ( ) . any ( |window| window. focused ) ;
813
- let should_update = match config. update_mode ( focused) {
814
- // `Reactive`: In order for `event_handler` to have been called, either
815
- // we received a window or raw input event, the `wait` elapsed, or a
816
- // redraw was requested (by the app or the OS). There are no other
817
- // conditions, so we can just return `true` here.
818
- UpdateMode :: Continuous | UpdateMode :: Reactive { .. } => true ,
819
- // TODO(bug): This is currently always true since we only run this function
820
- // if we received a `RequestRedraw` event.
821
- UpdateMode :: ReactiveLowPower { .. } => {
822
- runner_state. wait_elapsed
823
- || runner_state. redraw_requested
824
- || runner_state. window_event_received
825
- }
826
- } ;
827
870
828
- if app. plugins_state ( ) == PluginsState :: Cleaned && should_update {
829
- // reset these on each update
830
- runner_state. wait_elapsed = false ;
871
+ if app. plugins_state ( ) == PluginsState :: Cleaned {
831
872
runner_state. last_update = Instant :: now ( ) ;
832
873
833
874
app. update ( ) ;
834
875
835
876
// decide when to run the next update
836
- let ( config, _) = focused_windows_state. get ( & app. world ) ;
877
+ let ( config, windows) = focused_windows_state. get ( & app. world ) ;
878
+ let focused = windows. iter ( ) . any ( |window| window. focused ) ;
837
879
match config. update_mode ( focused) {
838
880
UpdateMode :: Continuous => {
839
881
runner_state. redraw_requested = true ;
0 commit comments