diff options
Diffstat (limited to '')
| -rw-r--r-- | winit/Cargo.toml | 2 | ||||
| -rw-r--r-- | winit/src/program.rs | 185 | ||||
| -rw-r--r-- | winit/src/program/state.rs | 5 | ||||
| -rw-r--r-- | winit/src/program/window_manager.rs | 16 | 
4 files changed, 119 insertions, 89 deletions
| diff --git a/winit/Cargo.toml b/winit/Cargo.toml index bd6feb00..10a6369b 100644 --- a/winit/Cargo.toml +++ b/winit/Cargo.toml @@ -22,7 +22,7 @@ x11 = ["winit/x11"]  wayland = ["winit/wayland"]  wayland-dlopen = ["winit/wayland-dlopen"]  wayland-csd-adwaita = ["winit/wayland-csd-adwaita"] -multi-window = ["iced_runtime/multi-window"] +unconditional-rendering = []  [dependencies]  iced_futures.workspace = true diff --git a/winit/src/program.rs b/winit/src/program.rs index 8d1eec3a..130bf220 100644 --- a/winit/src/program.rs +++ b/winit/src/program.rs @@ -758,12 +758,23 @@ async fn run_instance<P, C>(              }              Event::EventLoopAwakened(event) => {                  match event { +                    event::Event::NewEvents(event::StartCause::Init) => { +                        for (_id, window) in window_manager.iter_mut() { +                            window.raw.request_redraw(); +                        } +                    }                      event::Event::NewEvents( -                        event::StartCause::Init -                        | event::StartCause::ResumeTimeReached { .. }, +                        event::StartCause::ResumeTimeReached { .. },                      ) => { +                        let now = Instant::now(); +                          for (_id, window) in window_manager.iter_mut() { -                            window.raw.request_redraw(); +                            if let Some(redraw_at) = window.redraw_at { +                                if redraw_at <= now { +                                    window.raw.request_redraw(); +                                    window.redraw_at = None; +                                } +                            }                          }                      }                      event::Event::PlatformSpecific( @@ -807,11 +818,39 @@ async fn run_instance<P, C>(                              continue;                          }; -                        // TODO: Avoid redrawing all the time by forcing widgets to -                        // request redraws on state changes -                        // -                        // Then, we can use the `interface_state` here to decide if a redraw -                        // is needed right away, or simply wait until a specific time. +                        let physical_size = window.state.physical_size(); + +                        if physical_size.width == 0 || physical_size.height == 0 +                        { +                            continue; +                        } + +                        if window.viewport_version +                            != window.state.viewport_version() +                        { +                            let logical_size = window.state.logical_size(); + +                            debug.layout_started(); +                            let ui = user_interfaces +                                .remove(&id) +                                .expect("Remove user interface"); + +                            let _ = user_interfaces.insert( +                                id, +                                ui.relayout(logical_size, &mut window.renderer), +                            ); +                            debug.layout_finished(); + +                            compositor.configure_surface( +                                &mut window.surface, +                                physical_size.width, +                                physical_size.height, +                            ); + +                            window.viewport_version = +                                window.state.viewport_version(); +                        } +                          let redraw_event = core::Event::Window(                              window::Event::RedrawRequested(Instant::now()),                          ); @@ -857,81 +896,18 @@ async fn run_instance<P, C>(                              status: core::event::Status::Ignored,                          }); -                        let _ = control_sender.start_send(Control::ChangeFlow( -                            match ui_state { -                                user_interface::State::Updated { -                                    redraw_request: Some(redraw_request), -                                } => match redraw_request { -                                    window::RedrawRequest::NextFrame => { -                                        window.raw.request_redraw(); - -                                        ControlFlow::Wait -                                    } -                                    window::RedrawRequest::At(at) => { -                                        ControlFlow::WaitUntil(at) -                                    } -                                }, -                                _ => ControlFlow::Wait, -                            }, -                        )); - -                        let physical_size = window.state.physical_size(); - -                        if physical_size.width == 0 || physical_size.height == 0 +                        if let user_interface::State::Updated { +                            redraw_request: Some(redraw_request), +                        } = ui_state                          { -                            continue; -                        } - -                        if window.viewport_version -                            != window.state.viewport_version() -                        { -                            let logical_size = window.state.logical_size(); - -                            debug.layout_started(); -                            let ui = user_interfaces -                                .remove(&id) -                                .expect("Remove user interface"); - -                            let _ = user_interfaces.insert( -                                id, -                                ui.relayout(logical_size, &mut window.renderer), -                            ); -                            debug.layout_finished(); - -                            debug.draw_started(); -                            let new_mouse_interaction = user_interfaces -                                .get_mut(&id) -                                .expect("Get user interface") -                                .draw( -                                    &mut window.renderer, -                                    window.state.theme(), -                                    &renderer::Style { -                                        text_color: window.state.text_color(), -                                    }, -                                    window.state.cursor(), -                                ); -                            debug.draw_finished(); - -                            if new_mouse_interaction != window.mouse_interaction -                            { -                                window.raw.set_cursor( -                                    conversion::mouse_interaction( -                                        new_mouse_interaction, -                                    ), -                                ); - -                                window.mouse_interaction = -                                    new_mouse_interaction; +                            match redraw_request { +                                window::RedrawRequest::NextFrame => { +                                    window.raw.request_redraw(); +                                } +                                window::RedrawRequest::At(at) => { +                                    window.redraw_at = Some(at); +                                }                              } - -                            compositor.configure_surface( -                                &mut window.surface, -                                physical_size.width, -                                physical_size.height, -                            ); - -                            window.viewport_version = -                                window.state.viewport_version();                          }                          debug.render_started(); @@ -995,6 +971,13 @@ async fn run_instance<P, C>(                          if matches!(                              window_event, +                            winit::event::WindowEvent::Resized(_) +                        ) { +                            window.raw.request_redraw(); +                        } + +                        if matches!( +                            window_event,                              winit::event::WindowEvent::CloseRequested                          ) && window.exit_on_close_request                          { @@ -1031,7 +1014,10 @@ async fn run_instance<P, C>(                          }                      }                      event::Event::AboutToWait => { -                        if events.is_empty() && messages.is_empty() { +                        if events.is_empty() +                            && messages.is_empty() +                            && window_manager.is_idle() +                        {                              continue;                          } @@ -1065,13 +1051,27 @@ async fn run_instance<P, C>(                                      &mut messages,                                  ); +                            #[cfg(feature = "unconditional-rendering")]                              window.raw.request_redraw(); -                            if !uis_stale { -                                uis_stale = matches!( -                                    ui_state, -                                    user_interface::State::Outdated -                                ); +                            match ui_state { +                                #[cfg(not( +                                    feature = "unconditional-rendering" +                                ))] +                                user_interface::State::Updated { +                                    redraw_request: Some(redraw_request), +                                } => match redraw_request { +                                    window::RedrawRequest::NextFrame => { +                                        window.raw.request_redraw(); +                                    } +                                    window::RedrawRequest::At(at) => { +                                        window.redraw_at = Some(at); +                                    } +                                }, +                                user_interface::State::Outdated => { +                                    uis_stale = true; +                                } +                                user_interface::State::Updated { .. } => {}                              }                              for (event, status) in window_events @@ -1139,6 +1139,17 @@ async fn run_instance<P, C>(                                  actions = 0;                              }                          } + +                        if let Some(redraw_at) = window_manager.redraw_at() { +                            let _ = +                                control_sender.start_send(Control::ChangeFlow( +                                    ControlFlow::WaitUntil(redraw_at), +                                )); +                        } else { +                            let _ = control_sender.start_send( +                                Control::ChangeFlow(ControlFlow::Wait), +                            ); +                        }                      }                      _ => {}                  } diff --git a/winit/src/program/state.rs b/winit/src/program/state.rs index a7fa2788..b8a58960 100644 --- a/winit/src/program/state.rs +++ b/winit/src/program/state.rs @@ -190,7 +190,10 @@ where                          ..                      },                  .. -            } => _debug.toggle(), +            } => { +                _debug.toggle(); +                window.request_redraw(); +            }              _ => {}          }      } diff --git a/winit/src/program/window_manager.rs b/winit/src/program/window_manager.rs index 3d22e155..10a973fe 100644 --- a/winit/src/program/window_manager.rs +++ b/winit/src/program/window_manager.rs @@ -1,4 +1,5 @@  use crate::core::mouse; +use crate::core::time::Instant;  use crate::core::window::Id;  use crate::core::{Point, Size};  use crate::graphics::Compositor; @@ -62,6 +63,7 @@ where                  surface,                  renderer,                  mouse_interaction: mouse::Interaction::None, +                redraw_at: None,              },          ); @@ -74,6 +76,19 @@ where          self.entries.is_empty()      } +    pub fn is_idle(&self) -> bool { +        self.entries +            .values() +            .all(|window| window.redraw_at.is_none()) +    } + +    pub fn redraw_at(&self) -> Option<Instant> { +        self.entries +            .values() +            .filter_map(|window| window.redraw_at) +            .min() +    } +      pub fn first(&self) -> Option<&Window<P, C>> {          self.entries.first_key_value().map(|(_id, window)| window)      } @@ -138,6 +153,7 @@ where      pub mouse_interaction: mouse::Interaction,      pub surface: C::Surface,      pub renderer: P::Renderer, +    pub redraw_at: Option<Instant>,  }  impl<P, C> Window<P, C> | 
