@@ -160,12 +160,12 @@ fn load_icon(icon_data: epi::IconData) -> Option<glutin::window::Icon> {
160
160
// ----------------------------------------------------------------------------
161
161
162
162
/// Run an egui app
163
- pub fn run ( mut app : Box < dyn epi:: App > , native_options : & epi:: NativeOptions ) {
163
+ pub fn run ( mut app : Box < dyn epi:: App > , native_options : & epi:: NativeOptions ) -> ! {
164
164
#[ allow( unused_mut) ]
165
165
let mut storage = create_storage ( app. name ( ) ) ;
166
166
167
167
let window_settings = deserialize_window_settings ( & storage) ;
168
- let mut event_loop = glutin:: event_loop:: EventLoop :: with_user_event ( ) ;
168
+ let event_loop = glutin:: event_loop:: EventLoop :: with_user_event ( ) ;
169
169
let icon = native_options. icon_data . clone ( ) . and_then ( load_icon) ;
170
170
let display = create_display ( & * app, native_options, & window_settings, icon, & event_loop) ;
171
171
@@ -191,6 +191,8 @@ pub fn run(mut app: Box<dyn epi::App>, native_options: &epi::NativeOptions) {
191
191
192
192
let mut previous_frame_time = None ;
193
193
194
+ let mut is_focused = true ;
195
+
194
196
#[ cfg( feature = "persistence" ) ]
195
197
let mut last_auto_save = Instant :: now ( ) ;
196
198
@@ -220,68 +222,8 @@ pub fn run(mut app: Box<dyn epi::App>, native_options: &epi::NativeOptions) {
220
222
// eprintln!("Warmed up in {} ms", warm_up_start.elapsed().as_millis())
221
223
}
222
224
223
- let mut is_focused = true ;
224
- let mut running = true ;
225
- let mut repaint_asap = true ;
226
-
227
- while running {
228
- use glium:: glutin:: platform:: run_return:: EventLoopExtRunReturn as _;
229
- event_loop. run_return ( |event, _, control_flow| {
230
- use glium:: glutin:: event_loop:: ControlFlow ;
231
-
232
- * control_flow = ControlFlow :: Wait ;
233
-
234
- match event {
235
- // Platform-dependent event handlers to workaround a winit bug
236
- // See: https://github.com/rust-windowing/winit/issues/987
237
- // See: https://github.com/rust-windowing/winit/issues/1619
238
- glutin:: event:: Event :: RedrawEventsCleared if cfg ! ( windows) => {
239
- * control_flow = ControlFlow :: Exit ; // Time to redraw
240
- }
241
- glutin:: event:: Event :: RedrawRequested ( _) if !cfg ! ( windows) => {
242
- * control_flow = ControlFlow :: Exit ; // Time to redraw
243
- }
244
- glutin:: event:: Event :: MainEventsCleared => {
245
- if repaint_asap {
246
- * control_flow = ControlFlow :: Exit ; // Time to redraw
247
- } else {
248
- // Winit uses up all the CPU of one core when returning ControlFlow::Wait.
249
- // Sleeping here helps, but still uses 1-3% of CPU :(
250
- if is_focused || !egui. egui_input ( ) . hovered_files . is_empty ( ) {
251
- std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 10 ) ) ;
252
- } else {
253
- std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 50 ) ) ;
254
- }
255
- }
256
- }
257
- glutin:: event:: Event :: WindowEvent { event, .. } => {
258
- if egui. is_quit_event ( & event) {
259
- * control_flow = ControlFlow :: Exit ;
260
- running = false ;
261
- }
262
-
263
- if let glutin:: event:: WindowEvent :: Focused ( new_focused) = event {
264
- is_focused = new_focused;
265
- }
266
-
267
- egui. on_event ( & event) ;
268
-
269
- // TODO: ask egui if the events warrants a repaint instead of repainting on each event.
270
- display. gl_window ( ) . window ( ) . request_redraw ( ) ;
271
- repaint_asap = true ;
272
- }
273
- glutin:: event:: Event :: UserEvent ( RequestRepaintEvent ) => {
274
- display. gl_window ( ) . window ( ) . request_redraw ( ) ;
275
- * control_flow = ControlFlow :: Exit ; // Time to redraw
276
- }
277
-
278
- _ => ( ) ,
279
- }
280
- } ) ;
281
-
282
- repaint_asap = false ;
283
-
284
- if running {
225
+ event_loop. run ( move |event, _, control_flow| {
226
+ let mut redraw = || {
285
227
if !is_focused {
286
228
// On Mac, a minimized Window uses up all CPU: https://github.com/emilk/egui/issues/325
287
229
// We can't know if we are minimized: https://github.com/rust-windowing/winit/issues/208
@@ -349,11 +291,13 @@ pub fn run(mut app: Box<dyn epi::App>, native_options: &epi::NativeOptions) {
349
291
let _ = display. gl_window ( ) . window ( ) . drag_window ( ) ;
350
292
}
351
293
352
- if quit {
353
- running = false ;
294
+ * control_flow = if quit {
295
+ glutin :: event_loop :: ControlFlow :: Exit
354
296
} else if needs_repaint {
355
297
display. gl_window ( ) . window ( ) . request_redraw ( ) ;
356
- repaint_asap = true ;
298
+ glutin:: event_loop:: ControlFlow :: Poll
299
+ } else {
300
+ glutin:: event_loop:: ControlFlow :: Wait
357
301
} ;
358
302
}
359
303
@@ -376,24 +320,52 @@ pub fn run(mut app: Box<dyn epi::App>, native_options: &epi::NativeOptions) {
376
320
last_auto_save = now;
377
321
}
378
322
}
379
- }
380
- }
323
+ } ;
324
+
325
+ match event {
326
+ // Platform-dependent event handlers to workaround a winit bug
327
+ // See: https://github.com/rust-windowing/winit/issues/987
328
+ // See: https://github.com/rust-windowing/winit/issues/1619
329
+ glutin:: event:: Event :: RedrawEventsCleared if cfg ! ( windows) => redraw ( ) ,
330
+ glutin:: event:: Event :: RedrawRequested ( _) if !cfg ! ( windows) => redraw ( ) ,
331
+
332
+ glutin:: event:: Event :: WindowEvent { event, .. } => {
333
+ if egui. is_quit_event ( & event) {
334
+ * control_flow = glium:: glutin:: event_loop:: ControlFlow :: Exit ;
335
+ }
381
336
382
- app. on_exit ( ) ;
337
+ if let glutin:: event:: WindowEvent :: Focused ( new_focused) = event {
338
+ is_focused = new_focused;
339
+ }
383
340
384
- #[ cfg( feature = "persistence" ) ]
385
- if let Some ( storage) = & mut storage {
386
- if app. persist_native_window ( ) {
387
- epi:: set_value (
388
- storage. as_mut ( ) ,
389
- WINDOW_KEY ,
390
- & WindowSettings :: from_display ( & display) ,
391
- ) ;
392
- }
393
- if app. persist_egui_memory ( ) {
394
- epi:: set_value ( storage. as_mut ( ) , EGUI_MEMORY_KEY , & * egui. ctx ( ) . memory ( ) ) ;
341
+ egui. on_event ( & event) ;
342
+
343
+ display. gl_window ( ) . window ( ) . request_redraw ( ) ; // TODO: ask egui if the events warrants a repaint instead
344
+ }
345
+ glutin:: event:: Event :: LoopDestroyed => {
346
+ app. on_exit ( ) ;
347
+ #[ cfg( feature = "persistence" ) ]
348
+ if let Some ( storage) = & mut storage {
349
+ if app. persist_native_window ( ) {
350
+ epi:: set_value (
351
+ storage. as_mut ( ) ,
352
+ WINDOW_KEY ,
353
+ & WindowSettings :: from_display ( & display) ,
354
+ ) ;
355
+ }
356
+ if app. persist_egui_memory ( ) {
357
+ epi:: set_value ( storage. as_mut ( ) , EGUI_MEMORY_KEY , & * egui. ctx ( ) . memory ( ) ) ;
358
+ }
359
+ app. save ( storage. as_mut ( ) ) ;
360
+ storage. flush ( ) ;
361
+ }
362
+ }
363
+
364
+ glutin:: event:: Event :: UserEvent ( RequestRepaintEvent ) => {
365
+ display. gl_window ( ) . window ( ) . request_redraw ( ) ;
366
+ }
367
+
368
+ _ => ( ) ,
395
369
}
396
- app. save ( storage. as_mut ( ) ) ;
397
- storage. flush ( ) ;
398
- }
370
+ } ) ;
399
371
}
0 commit comments