diff options
Diffstat (limited to '')
| -rw-r--r-- | winit/src/application.rs | 79 | ||||
| -rw-r--r-- | winit/src/conversion.rs | 12 | ||||
| -rw-r--r-- | winit/src/lib.rs | 2 | ||||
| -rw-r--r-- | winit/src/window.rs | 2 | 
4 files changed, 76 insertions, 19 deletions
diff --git a/winit/src/application.rs b/winit/src/application.rs index 76553988..c66e08b2 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -9,7 +9,7 @@ use crate::mouse;  use crate::renderer;  use crate::widget::operation;  use crate::{ -    Command, Debug, Error, Executor, Proxy, Runtime, Settings, Size, +    Command, Debug, Error, Event, Executor, Proxy, Runtime, Settings, Size,      Subscription,  }; @@ -18,6 +18,7 @@ use iced_futures::futures::channel::mpsc;  use iced_graphics::compositor;  use iced_graphics::window;  use iced_native::program::Program; +use iced_native::time::Instant;  use iced_native::user_interface::{self, UserInterface};  pub use iced_native::application::{Appearance, StyleSheet}; @@ -184,7 +185,8 @@ where      let (compositor, renderer) = C::new(compositor_settings, Some(&window))?; -    let (mut sender, receiver) = mpsc::unbounded(); +    let (mut event_sender, event_receiver) = mpsc::unbounded(); +    let (control_sender, mut control_receiver) = mpsc::unbounded();      let mut instance = Box::pin({          let run_instance = run_instance::<A, E, C>( @@ -194,7 +196,8 @@ where              runtime,              proxy,              debug, -            receiver, +            event_receiver, +            control_sender,              init_command,              window,              settings.exit_on_close_request, @@ -232,13 +235,19 @@ where          };          if let Some(event) = event { -            sender.start_send(event).expect("Send event"); +            event_sender.start_send(event).expect("Send event");              let poll = instance.as_mut().poll(&mut context); -            *control_flow = match poll { -                task::Poll::Pending => ControlFlow::Wait, -                task::Poll::Ready(_) => ControlFlow::Exit, +            match poll { +                task::Poll::Pending => { +                    if let Ok(Some(flow)) = control_receiver.try_next() { +                        *control_flow = flow; +                    } +                } +                task::Poll::Ready(_) => { +                    *control_flow = ControlFlow::Exit; +                }              };          }      }) @@ -251,7 +260,10 @@ async fn run_instance<A, E, C>(      mut runtime: Runtime<E, Proxy<A::Message>, A::Message>,      mut proxy: winit::event_loop::EventLoopProxy<A::Message>,      mut debug: Debug, -    mut receiver: mpsc::UnboundedReceiver<winit::event::Event<'_, A::Message>>, +    mut event_receiver: mpsc::UnboundedReceiver< +        winit::event::Event<'_, A::Message>, +    >, +    mut control_sender: mpsc::UnboundedSender<winit::event_loop::ControlFlow>,      init_command: Command<A::Message>,      window: winit::window::Window,      exit_on_close_request: bool, @@ -263,6 +275,7 @@ async fn run_instance<A, E, C>(  {      use iced_futures::futures::stream::StreamExt;      use winit::event; +    use winit::event_loop::ControlFlow;      let mut clipboard = Clipboard::connect(&window);      let mut cache = user_interface::Cache::default(); @@ -307,13 +320,22 @@ async fn run_instance<A, E, C>(      let mut mouse_interaction = mouse::Interaction::default();      let mut events = Vec::new();      let mut messages = Vec::new(); +    let mut redraw_pending = false;      debug.startup_finished(); -    while let Some(event) = receiver.next().await { +    while let Some(event) = event_receiver.next().await {          match event { +            event::Event::NewEvents(start_cause) => { +                redraw_pending = matches!( +                    start_cause, +                    event::StartCause::Init +                        | event::StartCause::Poll +                        | event::StartCause::ResumeTimeReached { .. } +                ); +            }              event::Event::MainEventsCleared => { -                if events.is_empty() && messages.is_empty() { +                if !redraw_pending && events.is_empty() && messages.is_empty() {                      continue;                  } @@ -336,7 +358,7 @@ async fn run_instance<A, E, C>(                  if !messages.is_empty()                      || matches!(                          interface_state, -                        user_interface::State::Outdated, +                        user_interface::State::Outdated                      )                  {                      let mut cache = @@ -374,6 +396,23 @@ async fn run_instance<A, E, C>(                      }                  } +                // 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 redraw_event = Event::Window( +                    crate::window::Event::RedrawRequested(Instant::now()), +                ); + +                let (interface_state, _) = user_interface.update( +                    &[redraw_event.clone()], +                    state.cursor_position(), +                    &mut renderer, +                    &mut clipboard, +                    &mut messages, +                ); +                  debug.draw_started();                  let new_mouse_interaction = user_interface.draw(                      &mut renderer, @@ -394,6 +433,24 @@ async fn run_instance<A, E, C>(                  }                  window.request_redraw(); +                runtime +                    .broadcast((redraw_event, crate::event::Status::Ignored)); + +                let _ = control_sender.start_send(match interface_state { +                    user_interface::State::Updated { +                        redraw_request: Some(redraw_request), +                    } => match redraw_request { +                        crate::window::RedrawRequest::NextFrame => { +                            ControlFlow::Poll +                        } +                        crate::window::RedrawRequest::At(at) => { +                            ControlFlow::WaitUntil(at) +                        } +                    }, +                    _ => ControlFlow::Wait, +                }); + +                redraw_pending = false;              }              event::Event::PlatformSpecific(event::PlatformSpecific::MacOS(                  event::MacOS::ReceivedUrl(url), diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index 6c809d19..111afd83 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -1,7 +1,7 @@  //! Convert [`winit`] types into [`iced_native`] types, and viceversa.  //!  //! [`winit`]: https://github.com/rust-windowing/winit -//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.6/native +//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.7/native  use crate::keyboard;  use crate::mouse;  use crate::touch; @@ -228,7 +228,7 @@ pub fn mode(mode: Option<winit::window::Fullscreen>) -> window::Mode {  /// Converts a `MouseCursor` from [`iced_native`] to a [`winit`] cursor icon.  ///  /// [`winit`]: https://github.com/rust-windowing/winit -/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.6/native +/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.7/native  pub fn mouse_interaction(      interaction: mouse::Interaction,  ) -> winit::window::CursorIcon { @@ -252,7 +252,7 @@ pub fn mouse_interaction(  /// Converts a `MouseButton` from [`winit`] to an [`iced_native`] mouse button.  ///  /// [`winit`]: https://github.com/rust-windowing/winit -/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.6/native +/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.7/native  pub fn mouse_button(mouse_button: winit::event::MouseButton) -> mouse::Button {      match mouse_button {          winit::event::MouseButton::Left => mouse::Button::Left, @@ -268,7 +268,7 @@ pub fn mouse_button(mouse_button: winit::event::MouseButton) -> mouse::Button {  /// modifiers state.  ///  /// [`winit`]: https://github.com/rust-windowing/winit -/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.6/native +/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.7/native  pub fn modifiers(      modifiers: winit::event::ModifiersState,  ) -> keyboard::Modifiers { @@ -295,7 +295,7 @@ pub fn cursor_position(  /// Converts a `Touch` from [`winit`] to an [`iced_native`] touch event.  ///  /// [`winit`]: https://github.com/rust-windowing/winit -/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.6/native +/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.7/native  pub fn touch_event(      touch: winit::event::Touch,      scale_factor: f64, @@ -326,7 +326,7 @@ pub fn touch_event(  /// Converts a `VirtualKeyCode` from [`winit`] to an [`iced_native`] key code.  ///  /// [`winit`]: https://github.com/rust-windowing/winit -/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.6/native +/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.7/native  pub fn key_code(      virtual_keycode: winit::event::VirtualKeyCode,  ) -> keyboard::KeyCode { diff --git a/winit/src/lib.rs b/winit/src/lib.rs index 99a46850..76339a76 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -11,7 +11,7 @@  //! Additionally, a [`conversion`] module is available for users that decide to  //! implement a custom event loop.  //! -//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.6/native +//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.7/native  //! [`winit`]: https://github.com/rust-windowing/winit  //! [`conversion`]: crate::conversion  #