@@ -172,15 +172,15 @@ fn load_icon(icon_data: epi::IconData) -> Option<glutin::window::Icon> {
172
172
// ----------------------------------------------------------------------------
173
173
174
174
/// Run an egui app
175
- pub fn run ( mut app : Box < dyn epi:: App > , native_options : epi:: NativeOptions ) -> ! {
175
+ pub fn run ( mut app : Box < dyn epi:: App > , native_options : epi:: NativeOptions ) {
176
176
#[ allow( unused_mut) ]
177
177
let mut storage = create_storage ( app. name ( ) ) ;
178
178
179
179
#[ cfg( feature = "http" ) ]
180
180
let http = std:: sync:: Arc :: new ( crate :: http:: GliumHttp { } ) ;
181
181
182
182
let window_settings = deserialize_window_settings ( & storage) ;
183
- let event_loop = glutin:: event_loop:: EventLoop :: with_user_event ( ) ;
183
+ let mut event_loop = glutin:: event_loop:: EventLoop :: with_user_event ( ) ;
184
184
let icon = native_options. icon_data . clone ( ) . and_then ( load_icon) ;
185
185
let display = create_display ( & * app, & native_options, window_settings, icon, & event_loop) ;
186
186
@@ -208,8 +208,6 @@ pub fn run(mut app: Box<dyn epi::App>, native_options: epi::NativeOptions) -> !
208
208
209
209
let mut previous_frame_time = None ;
210
210
211
- let mut is_focused = true ;
212
-
213
211
#[ cfg( feature = "persistence" ) ]
214
212
let mut last_auto_save = Instant :: now ( ) ;
215
213
@@ -241,8 +239,67 @@ pub fn run(mut app: Box<dyn epi::App>, native_options: epi::NativeOptions) -> !
241
239
// eprintln!("Warmed up in {} ms", warm_up_start.elapsed().as_millis())
242
240
}
243
241
244
- event_loop. run ( move |event, _, control_flow| {
245
- let mut redraw = || {
242
+ let mut is_focused = true ;
243
+ let mut running = true ;
244
+ let mut repaint_asap = true ;
245
+
246
+ while running {
247
+ use glium:: glutin:: platform:: run_return:: EventLoopExtRunReturn as _;
248
+ event_loop. run_return ( |event, _, control_flow| {
249
+ use glium:: glutin:: event_loop:: ControlFlow ;
250
+
251
+ * control_flow = ControlFlow :: Wait ;
252
+
253
+ match event {
254
+ // Platform-dependent event handlers to workaround a winit bug
255
+ // See: https://github.com/rust-windowing/winit/issues/987
256
+ // See: https://github.com/rust-windowing/winit/issues/1619
257
+ glutin:: event:: Event :: RedrawEventsCleared if cfg ! ( windows) => {
258
+ * control_flow = ControlFlow :: Exit ; // Time to redraw
259
+ }
260
+ glutin:: event:: Event :: RedrawRequested ( _) if !cfg ! ( windows) => {
261
+ * control_flow = ControlFlow :: Exit ; // Time to redraw
262
+ }
263
+ glutin:: event:: Event :: MainEventsCleared => {
264
+ if repaint_asap {
265
+ * control_flow = ControlFlow :: Exit ; // Time to redraw
266
+ } else {
267
+ // Winit uses up all the CPU of one core when returning ControlFlow::Wait.
268
+ // Sleeping here helps, but still uses 1-3% of CPU :(
269
+ if is_focused {
270
+ std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 10 ) ) ;
271
+ } else {
272
+ std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 100 ) ) ;
273
+ }
274
+ }
275
+ }
276
+ glutin:: event:: Event :: WindowEvent { event, .. } => {
277
+ if egui. is_quit_event ( & event) {
278
+ * control_flow = ControlFlow :: Exit ;
279
+ running = false ;
280
+ }
281
+
282
+ if let glutin:: event:: WindowEvent :: Focused ( new_focused) = event {
283
+ is_focused = new_focused;
284
+ }
285
+
286
+ egui. on_event ( & event) ;
287
+
288
+ // TODO: ask egui if the events warrants a repaint instead of repainting on each event.
289
+ display. gl_window ( ) . window ( ) . request_redraw ( ) ;
290
+ }
291
+ glutin:: event:: Event :: UserEvent ( RequestRepaintEvent ) => {
292
+ display. gl_window ( ) . window ( ) . request_redraw ( ) ;
293
+ * control_flow = ControlFlow :: Exit ; // Time to redraw
294
+ }
295
+
296
+ _ => ( ) ,
297
+ }
298
+ } ) ;
299
+
300
+ repaint_asap = false ;
301
+
302
+ if running {
246
303
if !is_focused {
247
304
// On Mac, a minimized Window uses up all CPU: https://github.com/emilk/egui/issues/325
248
305
// We can't know if we are minimized: https://github.com/rust-windowing/winit/issues/208
@@ -299,13 +356,11 @@ pub fn run(mut app: Box<dyn epi::App>, native_options: epi::NativeOptions) -> !
299
356
) ;
300
357
}
301
358
302
- * control_flow = if quit {
303
- glutin :: event_loop :: ControlFlow :: Exit
359
+ if quit {
360
+ running = false ;
304
361
} else if needs_repaint {
305
362
display. gl_window ( ) . window ( ) . request_redraw ( ) ;
306
- glutin:: event_loop:: ControlFlow :: Poll
307
- } else {
308
- glutin:: event_loop:: ControlFlow :: Wait
363
+ repaint_asap = true ;
309
364
} ;
310
365
}
311
366
@@ -324,48 +379,20 @@ pub fn run(mut app: Box<dyn epi::App>, native_options: epi::NativeOptions) -> !
324
379
last_auto_save = now;
325
380
}
326
381
}
327
- } ;
328
-
329
- match event {
330
- // Platform-dependent event handlers to workaround a winit bug
331
- // See: https://github.com/rust-windowing/winit/issues/987
332
- // See: https://github.com/rust-windowing/winit/issues/1619
333
- glutin:: event:: Event :: RedrawEventsCleared if cfg ! ( windows) => redraw ( ) ,
334
- glutin:: event:: Event :: RedrawRequested ( _) if !cfg ! ( windows) => redraw ( ) ,
335
-
336
- glutin:: event:: Event :: WindowEvent { event, .. } => {
337
- if egui. is_quit_event ( & event) {
338
- * control_flow = glium:: glutin:: event_loop:: ControlFlow :: Exit ;
339
- }
340
-
341
- if let glutin:: event:: WindowEvent :: Focused ( new_focused) = event {
342
- is_focused = new_focused;
343
- }
344
-
345
- egui. on_event ( & event) ;
346
-
347
- display. gl_window ( ) . window ( ) . request_redraw ( ) ; // TODO: ask egui if the events warrants a repaint instead
348
- }
349
- glutin:: event:: Event :: LoopDestroyed => {
350
- app. on_exit ( ) ;
351
- #[ cfg( feature = "persistence" ) ]
352
- if let Some ( storage) = & mut storage {
353
- epi:: set_value (
354
- storage. as_mut ( ) ,
355
- WINDOW_KEY ,
356
- & WindowSettings :: from_display ( & display) ,
357
- ) ;
358
- epi:: set_value ( storage. as_mut ( ) , EGUI_MEMORY_KEY , & * egui. ctx ( ) . memory ( ) ) ;
359
- app. save ( storage. as_mut ( ) ) ;
360
- storage. flush ( ) ;
361
- }
362
- }
382
+ }
383
+ }
363
384
364
- glutin:: event:: Event :: UserEvent ( RequestRepaintEvent ) => {
365
- display. gl_window ( ) . window ( ) . request_redraw ( ) ;
366
- }
385
+ app. on_exit ( ) ;
367
386
368
- _ => ( ) ,
369
- }
370
- } ) ;
387
+ #[ cfg( feature = "persistence" ) ]
388
+ if let Some ( storage) = & mut storage {
389
+ epi:: set_value (
390
+ storage. as_mut ( ) ,
391
+ WINDOW_KEY ,
392
+ & WindowSettings :: from_display ( & display) ,
393
+ ) ;
394
+ epi:: set_value ( storage. as_mut ( ) , EGUI_MEMORY_KEY , & * egui. ctx ( ) . memory ( ) ) ;
395
+ app. save ( storage. as_mut ( ) ) ;
396
+ storage. flush ( ) ;
397
+ }
371
398
}
0 commit comments