Code cleanup, clearer comments + removed some unnecessary dupe;
Removed `Frames` struct return for `window::frames()` since we are just redrawing every window anyways; Interface dropping;
This commit is contained in:
parent
fa068b904a
commit
8ba1843080
11 changed files with 59 additions and 103 deletions
|
|
@ -46,8 +46,8 @@ chrome-trace = [
|
||||||
"iced_wgpu?/tracing",
|
"iced_wgpu?/tracing",
|
||||||
"iced_glow?/tracing",
|
"iced_glow?/tracing",
|
||||||
]
|
]
|
||||||
# Enables experimental multi-window support for iced_winit
|
# Enables experimental multi-window support for iced_winit + wgpu.
|
||||||
multi_window = ["iced_winit/multi_window"]
|
multi-window = ["iced_winit/multi-window"]
|
||||||
|
|
||||||
[badges]
|
[badges]
|
||||||
maintenance = { status = "actively-developed" }
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ publish = false
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
iced = { path = "../..", features = ["debug", "multi_window", "tokio"] }
|
iced = { path = "../..", features = ["debug", "multi-window", "tokio"] }
|
||||||
env_logger = "0.10.0"
|
env_logger = "0.10.0"
|
||||||
iced_native = { path = "../../native" }
|
iced_native = { path = "../../native" }
|
||||||
iced_lazy = { path = "../../lazy" }
|
iced_lazy = { path = "../../lazy" }
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ impl Application for SolarSystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn subscription(&self) -> Subscription<Message> {
|
fn subscription(&self) -> Subscription<Message> {
|
||||||
window::frames().map(|frame| Message::Tick(frame.at))
|
window::frames().map(Message::Tick)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,20 +30,9 @@ use crate::time::Instant;
|
||||||
///
|
///
|
||||||
/// In any case, this [`Subscription`] is useful to smoothly draw application-driven
|
/// In any case, this [`Subscription`] is useful to smoothly draw application-driven
|
||||||
/// animations without missing any frames.
|
/// animations without missing any frames.
|
||||||
pub fn frames() -> Subscription<Frame> {
|
pub fn frames() -> Subscription<Instant> {
|
||||||
subscription::raw_events(|event, _status| match event {
|
subscription::raw_events(|event, _status| match event {
|
||||||
crate::Event::Window(id, Event::RedrawRequested(at)) => {
|
crate::Event::Window(_, Event::RedrawRequested(at)) => Some(at),
|
||||||
Some(Frame { id, at })
|
|
||||||
}
|
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The returned `Frame` for a framerate subscription.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Frame {
|
|
||||||
/// The `window::Id` that the `Frame` was produced in.
|
|
||||||
pub id: Id,
|
|
||||||
/// The `Instant` at which the frame was produced.
|
|
||||||
pub at: Instant,
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,7 @@ pub mod touch;
|
||||||
pub mod widget;
|
pub mod widget;
|
||||||
pub mod window;
|
pub mod window;
|
||||||
|
|
||||||
#[cfg(all(not(feature = "glow"), feature = "multi_window"))]
|
#[cfg(all(not(feature = "glow"), feature = "multi-window"))]
|
||||||
pub mod multi_window;
|
pub mod multi_window;
|
||||||
|
|
||||||
#[cfg(all(not(feature = "glow"), feature = "wgpu"))]
|
#[cfg(all(not(feature = "glow"), feature = "wgpu"))]
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ pub trait Application: Sized {
|
||||||
window: window::Id,
|
window: window::Id,
|
||||||
) -> Element<'_, Self::Message, crate::Renderer<Self::Theme>>;
|
) -> Element<'_, Self::Message, crate::Renderer<Self::Theme>>;
|
||||||
|
|
||||||
/// Returns the scale factor of the [`Application`].
|
/// Returns the scale factor of the `window` of the [`Application`].
|
||||||
///
|
///
|
||||||
/// It can be used to dynamically control the size of the UI at runtime
|
/// It can be used to dynamically control the size of the UI at runtime
|
||||||
/// (i.e. zooming).
|
/// (i.e. zooming).
|
||||||
|
|
@ -160,7 +160,8 @@ pub trait Application: Sized {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Requests that the [`window`] be closed.
|
/// Returns the `Self::Message` that should be processed when a `window` is requested to
|
||||||
|
/// be closed.
|
||||||
fn close_requested(&self, window: window::Id) -> Self::Message;
|
fn close_requested(&self, window: window::Id) -> Self::Message;
|
||||||
|
|
||||||
/// Runs the [`Application`].
|
/// Runs the [`Application`].
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ chrome-trace = ["trace", "tracing-chrome"]
|
||||||
debug = ["iced_native/debug"]
|
debug = ["iced_native/debug"]
|
||||||
system = ["sysinfo"]
|
system = ["sysinfo"]
|
||||||
application = []
|
application = []
|
||||||
multi_window = []
|
multi-window = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
window_clipboard = "0.2"
|
window_clipboard = "0.2"
|
||||||
|
|
|
||||||
|
|
@ -743,7 +743,7 @@ pub fn run_command<A, E>(
|
||||||
}
|
}
|
||||||
window::Action::Spawn { .. } => {
|
window::Action::Spawn { .. } => {
|
||||||
log::info!(
|
log::info!(
|
||||||
"This is only available on `multi_window::Application`"
|
"Spawning a window is only available with `multi_window::Application`s."
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
window::Action::Resize { width, height } => {
|
window::Action::Resize { width, height } => {
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
pub use iced_native::*;
|
pub use iced_native::*;
|
||||||
pub use winit;
|
pub use winit;
|
||||||
|
|
||||||
#[cfg(feature = "multi_window")]
|
#[cfg(feature = "multi-window")]
|
||||||
pub mod multi_window;
|
pub mod multi_window;
|
||||||
|
|
||||||
#[cfg(feature = "application")]
|
#[cfg(feature = "application")]
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ use tracing::{info_span, instrument::Instrument};
|
||||||
|
|
||||||
/// This is a wrapper around the `Application::Message` associate type
|
/// This is a wrapper around the `Application::Message` associate type
|
||||||
/// to allows the `shell` to create internal messages, while still having
|
/// to allows the `shell` to create internal messages, while still having
|
||||||
/// the current user specified custom messages.
|
/// the current user-specified custom messages.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Event<Message> {
|
pub enum Event<Message> {
|
||||||
/// An [`Application`] generated message
|
/// An [`Application`] generated message
|
||||||
|
|
@ -53,9 +53,9 @@ pub enum Event<Message> {
|
||||||
WindowCreated(window::Id, winit::window::Window),
|
WindowCreated(window::Id, winit::window::Window),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An interactive, native cross-platform application.
|
/// An interactive, native, cross-platform, multi-windowed application.
|
||||||
///
|
///
|
||||||
/// This trait is the main entrypoint of Iced. Once implemented, you can run
|
/// This trait is the main entrypoint of multi-window Iced. Once implemented, you can run
|
||||||
/// your GUI application by simply calling [`run`]. It will run in
|
/// your GUI application by simply calling [`run`]. It will run in
|
||||||
/// its own window.
|
/// its own window.
|
||||||
///
|
///
|
||||||
|
|
@ -105,7 +105,7 @@ where
|
||||||
/// load state from a file, perform an initial HTTP request, etc.
|
/// load state from a file, perform an initial HTTP request, etc.
|
||||||
fn new(flags: Self::Flags) -> (Self, Command<Self::Message>);
|
fn new(flags: Self::Flags) -> (Self, Command<Self::Message>);
|
||||||
|
|
||||||
/// Returns the current title of each [`Application`] window.
|
/// Returns the current title of each window of the [`Application`].
|
||||||
///
|
///
|
||||||
/// This title can be dynamic! The runtime will automatically update the
|
/// This title can be dynamic! The runtime will automatically update the
|
||||||
/// title of your application when necessary.
|
/// title of your application when necessary.
|
||||||
|
|
@ -155,7 +155,8 @@ where
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Requests that the [`window`] be closed.
|
/// Returns the `Self::Message` that should be processed when a `window` is requested to
|
||||||
|
/// be closed.
|
||||||
fn close_requested(&self, window: window::Id) -> Self::Message;
|
fn close_requested(&self, window: window::Id) -> Self::Message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -462,9 +463,9 @@ async fn run_instance<A, E, C>(
|
||||||
}
|
}
|
||||||
debug.event_processing_finished();
|
debug.event_processing_finished();
|
||||||
|
|
||||||
// Update application with app message(s)
|
// Update application with app messages
|
||||||
// Note: without tying an app message to a window ID, we must redraw all windows
|
// Unless we implement some kind of diffing, we must redraw all windows as we
|
||||||
// as we cannot know what changed without some kind of damage tracking.
|
// cannot know what changed.
|
||||||
if !messages.is_empty()
|
if !messages.is_empty()
|
||||||
|| matches!(
|
|| matches!(
|
||||||
interface_state,
|
interface_state,
|
||||||
|
|
@ -612,9 +613,7 @@ async fn run_instance<A, E, C>(
|
||||||
}
|
}
|
||||||
Event::WindowCreated(id, window) => {
|
Event::WindowCreated(id, window) => {
|
||||||
let mut surface = compositor.create_surface(&window);
|
let mut surface = compositor.create_surface(&window);
|
||||||
|
|
||||||
let state = State::new(&application, id, &window);
|
let state = State::new(&application, id, &window);
|
||||||
|
|
||||||
let physical_size = state.physical_size();
|
let physical_size = state.physical_size();
|
||||||
|
|
||||||
compositor.configure_surface(
|
compositor.configure_surface(
|
||||||
|
|
@ -776,14 +775,12 @@ async fn run_instance<A, E, C>(
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
debug.render_finished();
|
debug.render_finished();
|
||||||
|
log::error!("Error {error:?} when presenting surface.");
|
||||||
|
|
||||||
// Try rendering again next frame.
|
// Try rendering windows again next frame.
|
||||||
// TODO(derezzedex)
|
for window in windows.values() {
|
||||||
windows
|
window.request_redraw();
|
||||||
.values()
|
}
|
||||||
.next()
|
|
||||||
.expect("No window found")
|
|
||||||
.request_redraw();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -792,80 +789,45 @@ async fn run_instance<A, E, C>(
|
||||||
event: window_event,
|
event: window_event,
|
||||||
window_id,
|
window_id,
|
||||||
} => {
|
} => {
|
||||||
// dbg!(window_id);
|
if let (Some(window), Some(state)) = (
|
||||||
if let Some(window) =
|
window_ids.get(&window_id).and_then(|id| windows.get(id)),
|
||||||
window_ids.get(&window_id).and_then(|id| windows.get(id))
|
window_ids
|
||||||
{
|
|
||||||
if let Some(state) = window_ids
|
|
||||||
.get(&window_id)
|
.get(&window_id)
|
||||||
.and_then(|id| states.get_mut(id))
|
.and_then(|id| states.get_mut(id)),
|
||||||
{
|
) {
|
||||||
if requests_exit(&window_event, state.modifiers()) {
|
if crate::application::requests_exit(&window_event, state.modifiers()) {
|
||||||
if let Some(id) =
|
if let Some(id) = window_ids.get(&window_id).cloned() {
|
||||||
window_ids.get(&window_id).cloned()
|
let message = application.close_requested(id);
|
||||||
{
|
messages.push(message);
|
||||||
let message = application.close_requested(id);
|
|
||||||
messages.push(message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
state.update(window, &window_event, &mut debug);
|
state.update(window, &window_event, &mut debug);
|
||||||
|
|
||||||
if let Some(event) = conversion::window_event(
|
if let Some(event) = conversion::window_event(
|
||||||
*window_ids.get(&window_id).unwrap(),
|
*window_ids.get(&window_id).unwrap(),
|
||||||
&window_event,
|
&window_event,
|
||||||
state.scale_factor(),
|
state.scale_factor(),
|
||||||
state.modifiers(),
|
state.modifiers(),
|
||||||
) {
|
) {
|
||||||
events.push((
|
events
|
||||||
window_ids.get(&window_id).cloned(),
|
.push((window_ids.get(&window_id).cloned(), event));
|
||||||
event,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log::error!(
|
|
||||||
"No window state found for id: {:?}",
|
|
||||||
window_id
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log::error!("No window found with id: {:?}", window_id);
|
log::error!(
|
||||||
|
"Could not find window or state for id: {window_id:?}"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manually drop the user interface
|
// Manually drop the user interfaces
|
||||||
// drop(ManuallyDrop::into_inner(user_interface));
|
drop(ManuallyDrop::into_inner(interfaces));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the provided event should cause an [`Application`] to
|
/// Builds a window's [`UserInterface`] for the [`Application`].
|
||||||
/// exit.
|
|
||||||
pub fn requests_exit(
|
|
||||||
event: &winit::event::WindowEvent<'_>,
|
|
||||||
_modifiers: winit::event::ModifiersState,
|
|
||||||
) -> bool {
|
|
||||||
use winit::event::WindowEvent;
|
|
||||||
|
|
||||||
match event {
|
|
||||||
WindowEvent::CloseRequested => true,
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
WindowEvent::KeyboardInput {
|
|
||||||
input:
|
|
||||||
winit::event::KeyboardInput {
|
|
||||||
virtual_keycode: Some(winit::event::VirtualKeyCode::Q),
|
|
||||||
state: winit::event::ElementState::Pressed,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
..
|
|
||||||
} if _modifiers.logo() => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Builds a [`UserInterface`] for the provided [`Application`], logging
|
|
||||||
/// [`struct@Debug`] information accordingly.
|
|
||||||
pub fn build_user_interface<'a, A: Application>(
|
pub fn build_user_interface<'a, A: Application>(
|
||||||
application: &'a A,
|
application: &'a A,
|
||||||
cache: user_interface::Cache,
|
cache: user_interface::Cache,
|
||||||
|
|
@ -890,7 +852,9 @@ where
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "trace")]
|
||||||
let layout_span = info_span!("Application", "LAYOUT").entered();
|
let layout_span = info_span!("Application", "LAYOUT").entered();
|
||||||
debug.layout_started();
|
debug.layout_started();
|
||||||
|
|
||||||
let user_interface = UserInterface::build(view, size, cache, renderer);
|
let user_interface = UserInterface::build(view, size, cache, renderer);
|
||||||
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "trace")]
|
||||||
let _ = layout_span.exit();
|
let _ = layout_span.exit();
|
||||||
debug.layout_finished();
|
debug.layout_finished();
|
||||||
|
|
@ -898,7 +862,7 @@ where
|
||||||
user_interface
|
user_interface
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates an [`Application`] by feeding it the provided messages, spawning any
|
/// Updates an [`Application`] by feeding it messages, spawning any
|
||||||
/// resulting [`Command`], and tracking its [`Subscription`].
|
/// resulting [`Command`], and tracking its [`Subscription`].
|
||||||
pub fn update<A: Application, E: Executor>(
|
pub fn update<A: Application, E: Executor>(
|
||||||
application: &mut A,
|
application: &mut A,
|
||||||
|
|
@ -923,7 +887,9 @@ pub fn update<A: Application, E: Executor>(
|
||||||
debug.log_message(&message);
|
debug.log_message(&message);
|
||||||
|
|
||||||
debug.update_started();
|
debug.update_started();
|
||||||
|
|
||||||
let command = runtime.enter(|| application.update(message));
|
let command = runtime.enter(|| application.update(message));
|
||||||
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "trace")]
|
||||||
let _ = update_span.exit();
|
let _ = update_span.exit();
|
||||||
debug.update_finished();
|
debug.update_finished();
|
||||||
|
|
@ -1023,7 +989,7 @@ pub fn run_command<A, E>(
|
||||||
let window = windows.get(&id).expect("No window found");
|
let window = windows.get(&id).expect("No window found");
|
||||||
window.set_visible(conversion::visible(mode));
|
window.set_visible(conversion::visible(mode));
|
||||||
window.set_fullscreen(conversion::fullscreen(
|
window.set_fullscreen(conversion::fullscreen(
|
||||||
window.primary_monitor(),
|
window.current_monitor(),
|
||||||
mode,
|
mode,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ where
|
||||||
/// Synchronizes the [`State`] with its [`Application`] and its respective
|
/// Synchronizes the [`State`] with its [`Application`] and its respective
|
||||||
/// window.
|
/// window.
|
||||||
///
|
///
|
||||||
/// Normally an [`Application`] should be synchronized with its [`State`]
|
/// Normally, an [`Application`] should be synchronized with its [`State`]
|
||||||
/// and window after calling [`Application::update`].
|
/// and window after calling [`Application::update`].
|
||||||
///
|
///
|
||||||
/// [`Application::update`]: crate::Program::update
|
/// [`Application::update`]: crate::Program::update
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue