diff options
| author | 2024-01-17 08:05:19 +0100 | |
|---|---|---|
| committer | 2024-01-17 08:05:19 +0100 | |
| commit | 985acb2b1532b3e56161bd35201c4a2e21a86b85 (patch) | |
| tree | 7b100257baf72dbceccf5c3343abf3a6b9f1db03 /winit/src | |
| parent | 03f5a351c37dbe1b0a286583e620d1cf074f1b91 (diff) | |
| download | iced-985acb2b1532b3e56161bd35201c4a2e21a86b85.tar.gz iced-985acb2b1532b3e56161bd35201c4a2e21a86b85.tar.bz2 iced-985acb2b1532b3e56161bd35201c4a2e21a86b85.zip  | |
Fine-tune event loop of `multi-window` applications
Diffstat (limited to '')
| -rw-r--r-- | winit/src/multi_window.rs | 219 | 
1 files changed, 123 insertions, 96 deletions
diff --git a/winit/src/multi_window.rs b/winit/src/multi_window.rs index dc659c1a..84c81bea 100644 --- a/winit/src/multi_window.rs +++ b/winit/src/multi_window.rs @@ -229,7 +229,21 @@ where                  task::Poll::Pending => match control_receiver.try_next() {                      Ok(Some(control)) => match control {                          Control::ChangeFlow(flow) => { -                            event_loop.set_control_flow(flow); +                            use winit::event_loop::ControlFlow; + +                            match (event_loop.control_flow(), flow) { +                                ( +                                    ControlFlow::WaitUntil(current), +                                    ControlFlow::WaitUntil(new), +                                ) if new < current => {} +                                ( +                                    ControlFlow::WaitUntil(target), +                                    ControlFlow::Wait, +                                ) if target > Instant::now() => {} +                                _ => { +                                    event_loop.set_control_flow(flow); +                                } +                            }                          }                          Control::CreateWindow {                              id, @@ -362,7 +376,6 @@ async fn run_instance<A, E, C>(      runtime.track(application.subscription().into_recipes());      let mut messages = Vec::new(); -    let mut redraw_pending = false;      debug.startup_finished(); @@ -409,13 +422,15 @@ async fn run_instance<A, E, C>(              }              Event::EventLoopAwakened(event) => {                  match event { -                    event::Event::NewEvents(start_cause) => { -                        redraw_pending = matches!( -                            start_cause, -                            event::StartCause::Init -                                | event::StartCause::Poll -                                | event::StartCause::ResumeTimeReached { .. } -                        ); +                    event::Event::NewEvents( +                        event::StartCause::Init +                        | event::StartCause::ResumeTimeReached { .. }, +                    ) => { +                        for (_id, window) in window_manager.iter_mut() { +                            // TODO once widgets can request to be redrawn, we can avoid always requesting a +                            // redraw +                            window.raw.request_redraw(); +                        }                      }                      event::Event::PlatformSpecific(                          event::PlatformSpecific::MacOS( @@ -503,7 +518,9 @@ async fn run_instance<A, E, C>(                                      redraw_request: Some(redraw_request),                                  } => match redraw_request {                                      window::RedrawRequest::NextFrame => { -                                        ControlFlow::Poll +                                        window.raw.request_redraw(); + +                                        ControlFlow::Wait                                      }                                      window::RedrawRequest::At(at) => {                                          ControlFlow::WaitUntil(at) @@ -653,103 +670,113 @@ async fn run_instance<A, E, C>(                              }                          }                      } -                    _ => {} -                } -            } -        } +                    event::Event::AboutToWait => { +                        if events.is_empty() && messages.is_empty() { +                            continue; +                        } -        debug.event_processing_started(); -        let mut uis_stale = false; +                        debug.event_processing_started(); +                        let mut uis_stale = false; -        for (id, window) in window_manager.iter_mut() { -            let mut window_events = vec![]; +                        for (id, window) in window_manager.iter_mut() { +                            let mut window_events = vec![]; -            events.retain(|(window_id, event)| { -                if *window_id == Some(id) || window_id.is_none() { -                    window_events.push(event.clone()); -                    false -                } else { -                    true -                } -            }); +                            events.retain(|(window_id, event)| { +                                if *window_id == Some(id) || window_id.is_none() +                                { +                                    window_events.push(event.clone()); +                                    false +                                } else { +                                    true +                                } +                            }); -            if !redraw_pending -                && window_events.is_empty() -                && messages.is_empty() -            { -                continue; -            } +                            if window_events.is_empty() && messages.is_empty() { +                                continue; +                            } -            let (ui_state, statuses) = user_interfaces -                .get_mut(&id) -                .expect("Get user interface") -                .update( -                    &window_events, -                    window.state.cursor(), -                    &mut window.renderer, -                    &mut clipboard, -                    &mut messages, -                ); +                            let (ui_state, statuses) = user_interfaces +                                .get_mut(&id) +                                .expect("Get user interface") +                                .update( +                                    &window_events, +                                    window.state.cursor(), +                                    &mut window.renderer, +                                    &mut clipboard, +                                    &mut messages, +                                ); -            if !uis_stale { -                uis_stale = matches!(ui_state, user_interface::State::Outdated); -            } +                            window.raw.request_redraw(); -            for (event, status) in -                window_events.into_iter().zip(statuses.into_iter()) -            { -                runtime.broadcast(event, status); -            } -        } +                            if !uis_stale { +                                uis_stale = matches!( +                                    ui_state, +                                    user_interface::State::Outdated +                                ); +                            } -        debug.event_processing_finished(); - -        // TODO mw application update returns which window IDs to update -        if !messages.is_empty() || uis_stale { -            let mut cached_interfaces: HashMap< -                window::Id, -                user_interface::Cache, -            > = ManuallyDrop::into_inner(user_interfaces) -                .drain() -                .map(|(id, ui)| (id, ui.into_cache())) -                .collect(); - -            // Update application -            update( -                &mut application, -                &mut compositor, -                &mut runtime, -                &mut clipboard, -                &mut control_sender, -                &mut proxy, -                &mut debug, -                &mut messages, -                &mut window_manager, -                &mut cached_interfaces, -            ); - -            // we must synchronize all window states with application state after an -            // application update since we don't know what changed -            for (id, window) in window_manager.iter_mut() { -                window.state.synchronize(&application, id, &window.raw); -            } +                            for (event, status) in window_events +                                .into_iter() +                                .zip(statuses.into_iter()) +                            { +                                runtime.broadcast(event, status); +                            } +                        } -            // rebuild UIs with the synchronized states -            user_interfaces = ManuallyDrop::new(build_user_interfaces( -                &application, -                &mut debug, -                &mut window_manager, -                cached_interfaces, -            )); -        } +                        debug.event_processing_finished(); + +                        // TODO mw application update returns which window IDs to update +                        if !messages.is_empty() || uis_stale { +                            let mut cached_interfaces: HashMap< +                                window::Id, +                                user_interface::Cache, +                            > = ManuallyDrop::into_inner(user_interfaces) +                                .drain() +                                .map(|(id, ui)| (id, ui.into_cache())) +                                .collect(); + +                            // Update application +                            update( +                                &mut application, +                                &mut compositor, +                                &mut runtime, +                                &mut clipboard, +                                &mut control_sender, +                                &mut proxy, +                                &mut debug, +                                &mut messages, +                                &mut window_manager, +                                &mut cached_interfaces, +                            ); -        for (_id, window) in window_manager.iter_mut() { -            // TODO once widgets can request to be redrawn, we can avoid always requesting a -            // redraw -            window.raw.request_redraw(); -        } +                            // we must synchronize all window states with application state after an +                            // application update since we don't know what changed +                            for (id, window) in window_manager.iter_mut() { +                                window.state.synchronize( +                                    &application, +                                    id, +                                    &window.raw, +                                ); + +                                // TODO once widgets can request to be redrawn, we can avoid always requesting a +                                // redraw +                                window.raw.request_redraw(); +                            } -        redraw_pending = false; +                            // rebuild UIs with the synchronized states +                            user_interfaces = +                                ManuallyDrop::new(build_user_interfaces( +                                    &application, +                                    &mut debug, +                                    &mut window_manager, +                                    cached_interfaces, +                                )); +                        } +                    } +                    _ => {} +                } +            } +        }      }      let _ = ManuallyDrop::into_inner(user_interfaces);  | 
