Implement widget redraw support in iced_glutin
This commit is contained in:
parent
7354f68b3c
commit
a980024bbf
1 changed files with 61 additions and 11 deletions
|
|
@ -12,10 +12,11 @@ use iced_winit::futures;
|
||||||
use iced_winit::futures::channel::mpsc;
|
use iced_winit::futures::channel::mpsc;
|
||||||
use iced_winit::renderer;
|
use iced_winit::renderer;
|
||||||
use iced_winit::user_interface;
|
use iced_winit::user_interface;
|
||||||
use iced_winit::{Clipboard, Command, Debug, Proxy, Settings};
|
use iced_winit::{Clipboard, Command, Debug, Event, Proxy, Settings};
|
||||||
|
|
||||||
use glutin::window::Window;
|
use glutin::window::Window;
|
||||||
use std::mem::ManuallyDrop;
|
use std::mem::ManuallyDrop;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
#[cfg(feature = "tracing")]
|
#[cfg(feature = "tracing")]
|
||||||
use tracing::{info_span, instrument::Instrument};
|
use tracing::{info_span, instrument::Instrument};
|
||||||
|
|
@ -131,7 +132,8 @@ where
|
||||||
})?
|
})?
|
||||||
};
|
};
|
||||||
|
|
||||||
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 mut instance = Box::pin({
|
||||||
let run_instance = run_instance::<A, E, C>(
|
let run_instance = run_instance::<A, E, C>(
|
||||||
|
|
@ -141,7 +143,8 @@ where
|
||||||
runtime,
|
runtime,
|
||||||
proxy,
|
proxy,
|
||||||
debug,
|
debug,
|
||||||
receiver,
|
event_receiver,
|
||||||
|
control_sender,
|
||||||
context,
|
context,
|
||||||
init_command,
|
init_command,
|
||||||
settings.exit_on_close_request,
|
settings.exit_on_close_request,
|
||||||
|
|
@ -179,14 +182,20 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(event) = event {
|
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);
|
let poll = instance.as_mut().poll(&mut context);
|
||||||
|
|
||||||
*control_flow = match poll {
|
match poll {
|
||||||
task::Poll::Pending => ControlFlow::Wait,
|
task::Poll::Pending => {
|
||||||
task::Poll::Ready(_) => ControlFlow::Exit,
|
if let Ok(Some(flow)) = control_receiver.try_next() {
|
||||||
};
|
*control_flow = flow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
task::Poll::Ready(_) => {
|
||||||
|
*control_flow = ControlFlow::Exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -200,7 +209,10 @@ async fn run_instance<A, E, C>(
|
||||||
mut runtime: Runtime<E, Proxy<A::Message>, A::Message>,
|
mut runtime: Runtime<E, Proxy<A::Message>, A::Message>,
|
||||||
mut proxy: glutin::event_loop::EventLoopProxy<A::Message>,
|
mut proxy: glutin::event_loop::EventLoopProxy<A::Message>,
|
||||||
mut debug: Debug,
|
mut debug: Debug,
|
||||||
mut receiver: mpsc::UnboundedReceiver<glutin::event::Event<'_, A::Message>>,
|
mut event_receiver: mpsc::UnboundedReceiver<
|
||||||
|
glutin::event::Event<'_, A::Message>,
|
||||||
|
>,
|
||||||
|
mut control_sender: mpsc::UnboundedSender<glutin::event_loop::ControlFlow>,
|
||||||
mut context: glutin::ContextWrapper<glutin::PossiblyCurrent, Window>,
|
mut context: glutin::ContextWrapper<glutin::PossiblyCurrent, Window>,
|
||||||
init_command: Command<A::Message>,
|
init_command: Command<A::Message>,
|
||||||
exit_on_close_request: bool,
|
exit_on_close_request: bool,
|
||||||
|
|
@ -211,6 +223,7 @@ async fn run_instance<A, E, C>(
|
||||||
<A::Renderer as iced_native::Renderer>::Theme: StyleSheet,
|
<A::Renderer as iced_native::Renderer>::Theme: StyleSheet,
|
||||||
{
|
{
|
||||||
use glutin::event;
|
use glutin::event;
|
||||||
|
use glutin::event_loop::ControlFlow;
|
||||||
use iced_winit::futures::stream::StreamExt;
|
use iced_winit::futures::stream::StreamExt;
|
||||||
|
|
||||||
let mut clipboard = Clipboard::connect(context.window());
|
let mut clipboard = Clipboard::connect(context.window());
|
||||||
|
|
@ -247,13 +260,21 @@ async fn run_instance<A, E, C>(
|
||||||
let mut mouse_interaction = mouse::Interaction::default();
|
let mut mouse_interaction = mouse::Interaction::default();
|
||||||
let mut events = Vec::new();
|
let mut events = Vec::new();
|
||||||
let mut messages = Vec::new();
|
let mut messages = Vec::new();
|
||||||
|
let mut redraw_pending = false;
|
||||||
|
|
||||||
debug.startup_finished();
|
debug.startup_finished();
|
||||||
|
|
||||||
while let Some(event) = receiver.next().await {
|
while let Some(event) = event_receiver.next().await {
|
||||||
match event {
|
match event {
|
||||||
|
event::Event::NewEvents(start_cause) => {
|
||||||
|
redraw_pending = matches!(
|
||||||
|
start_cause,
|
||||||
|
event::StartCause::Init
|
||||||
|
| event::StartCause::ResumeTimeReached { .. }
|
||||||
|
);
|
||||||
|
}
|
||||||
event::Event::MainEventsCleared => {
|
event::Event::MainEventsCleared => {
|
||||||
if events.is_empty() && messages.is_empty() {
|
if !redraw_pending && events.is_empty() && messages.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -315,6 +336,24 @@ 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 whether
|
||||||
|
// 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();
|
debug.draw_started();
|
||||||
let new_mouse_interaction = user_interface.draw(
|
let new_mouse_interaction = user_interface.draw(
|
||||||
&mut renderer,
|
&mut renderer,
|
||||||
|
|
@ -335,6 +374,17 @@ async fn run_instance<A, E, C>(
|
||||||
}
|
}
|
||||||
|
|
||||||
context.window().request_redraw();
|
context.window().request_redraw();
|
||||||
|
runtime
|
||||||
|
.broadcast((redraw_event, crate::event::Status::Ignored));
|
||||||
|
|
||||||
|
let _ = control_sender.start_send(match interface_state {
|
||||||
|
user_interface::State::Updated {
|
||||||
|
redraw_requested_at: Some(at),
|
||||||
|
} => ControlFlow::WaitUntil(at),
|
||||||
|
_ => ControlFlow::Wait,
|
||||||
|
});
|
||||||
|
|
||||||
|
redraw_pending = false;
|
||||||
}
|
}
|
||||||
event::Event::PlatformSpecific(event::PlatformSpecific::MacOS(
|
event::Event::PlatformSpecific(event::PlatformSpecific::MacOS(
|
||||||
event::MacOS::ReceivedUrl(url),
|
event::MacOS::ReceivedUrl(url),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue