Merge remote-tracking branch 'origin/master' into feat/multi-window-support

# Conflicts:
#	examples/events/src/main.rs
#	glutin/src/application.rs
#	native/src/window.rs
#	winit/src/window.rs
This commit is contained in:
Bingus 2023-01-18 15:01:17 -08:00
commit 70d487ba20
No known key found for this signature in database
GPG key ID: 5F84D2AA40A9F170
57 changed files with 815 additions and 446 deletions

View file

@ -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),

View file

@ -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 {

View file

@ -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
#![doc(

View file

@ -2,7 +2,7 @@
use crate::command::{self, Command};
use iced_native::window;
pub use window::{Event, Id, Mode, UserAttention};
pub use window::{Event, Id, Mode, RedrawRequest, frames, UserAttention};
/// Closes the window.
pub fn close<Message>(id: window::Id) -> Command<Message> {