Introduce window::Id to Event subscriptions
And remove `window::Id` from `Event` altogether.
This commit is contained in:
parent
49affc44ff
commit
e400f972c1
19 changed files with 95 additions and 91 deletions
|
|
@ -19,7 +19,7 @@ pub enum Event {
|
|||
Mouse(mouse::Event),
|
||||
|
||||
/// A window event
|
||||
Window(window::Id, window::Event),
|
||||
Window(window::Event),
|
||||
|
||||
/// A touch event
|
||||
Touch(touch::Event),
|
||||
|
|
|
|||
|
|
@ -37,9 +37,8 @@ impl Events {
|
|||
Command::none()
|
||||
}
|
||||
Message::EventOccurred(event) => {
|
||||
if let Event::Window(id, window::Event::CloseRequested) = event
|
||||
{
|
||||
window::close(id)
|
||||
if let Event::Window(window::Event::CloseRequested) = event {
|
||||
window::close(window::Id::MAIN)
|
||||
} else {
|
||||
Command::none()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ use iced_wgpu::{wgpu, Engine, Renderer};
|
|||
use iced_winit::conversion;
|
||||
use iced_winit::core::mouse;
|
||||
use iced_winit::core::renderer;
|
||||
use iced_winit::core::window;
|
||||
use iced_winit::core::{Color, Font, Pixels, Size, Theme};
|
||||
use iced_winit::futures;
|
||||
use iced_winit::runtime::program;
|
||||
|
|
@ -317,7 +316,6 @@ pub fn main() -> Result<(), winit::error::EventLoopError> {
|
|||
|
||||
// Map window event to iced event
|
||||
if let Some(event) = iced_winit::conversion::window_event(
|
||||
window::Id::MAIN,
|
||||
event,
|
||||
window.scale_factor(),
|
||||
*modifiers,
|
||||
|
|
|
|||
|
|
@ -275,7 +275,7 @@ where
|
|||
) -> event::Status {
|
||||
let state = tree.state.downcast_mut::<State>();
|
||||
|
||||
if let Event::Window(_, window::Event::RedrawRequested(now)) = event {
|
||||
if let Event::Window(window::Event::RedrawRequested(now)) = event {
|
||||
state.animation = state.animation.timed_transition(
|
||||
self.cycle_duration,
|
||||
self.rotation_duration,
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ where
|
|||
) -> event::Status {
|
||||
let state = tree.state.downcast_mut::<State>();
|
||||
|
||||
if let Event::Window(_, window::Event::RedrawRequested(now)) = event {
|
||||
if let Event::Window(window::Event::RedrawRequested(now)) = event {
|
||||
*state = state.timed_transition(self.cycle_duration, now);
|
||||
|
||||
shell.request_redraw(RedrawRequest::NextFrame);
|
||||
|
|
|
|||
|
|
@ -145,16 +145,18 @@ impl multi_window::Application for Example {
|
|||
}
|
||||
|
||||
fn subscription(&self) -> Subscription<Self::Message> {
|
||||
event::listen_with(|event, _| {
|
||||
if let iced::Event::Window(id, window_event) = event {
|
||||
event::listen_with(|event, _, window| {
|
||||
if let iced::Event::Window(window_event) = event {
|
||||
match window_event {
|
||||
window::Event::CloseRequested => {
|
||||
Some(Message::CloseWindow(id))
|
||||
Some(Message::CloseWindow(window))
|
||||
}
|
||||
window::Event::Opened { position, .. } => {
|
||||
Some(Message::WindowOpened(id, position))
|
||||
Some(Message::WindowOpened(window, position))
|
||||
}
|
||||
window::Event::Closed => {
|
||||
Some(Message::WindowClosed(window))
|
||||
}
|
||||
window::Event::Closed => Some(Message::WindowClosed(id)),
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -499,9 +499,7 @@ mod toast {
|
|||
clipboard: &mut dyn Clipboard,
|
||||
shell: &mut Shell<'_, Message>,
|
||||
) -> event::Status {
|
||||
if let Event::Window(_, window::Event::RedrawRequested(now)) =
|
||||
&event
|
||||
{
|
||||
if let Event::Window(window::Event::RedrawRequested(now)) = &event {
|
||||
let mut next_redraw: Option<window::RedrawRequest> = None;
|
||||
|
||||
self.instants.iter_mut().enumerate().for_each(
|
||||
|
|
|
|||
|
|
@ -145,11 +145,11 @@ impl Example {
|
|||
}
|
||||
|
||||
fn subscription(&self) -> Subscription<Message> {
|
||||
event::listen_with(|event, _| match event {
|
||||
event::listen_with(|event, _status, _window| match event {
|
||||
Event::Mouse(mouse::Event::CursorMoved { position }) => {
|
||||
Some(Message::MouseMoved(position))
|
||||
}
|
||||
Event::Window(_, window::Event::Resized { .. }) => {
|
||||
Event::Window(window::Event::Resized { .. }) => {
|
||||
Some(Message::WindowResized)
|
||||
}
|
||||
_ => None,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use crate::MaybeSend;
|
|||
/// This subscription will notify your application of any [`Event`] that was
|
||||
/// not captured by any widget.
|
||||
pub fn listen() -> Subscription<Event> {
|
||||
listen_with(|event, status| match status {
|
||||
listen_with(|event, status, _window| match status {
|
||||
event::Status::Ignored => Some(event),
|
||||
event::Status::Captured => None,
|
||||
})
|
||||
|
|
@ -24,7 +24,7 @@ pub fn listen() -> Subscription<Event> {
|
|||
/// - Returns `None`, the [`Event`] will be discarded.
|
||||
/// - Returns `Some` message, the `Message` will be produced.
|
||||
pub fn listen_with<Message>(
|
||||
f: fn(Event, event::Status) -> Option<Message>,
|
||||
f: fn(Event, event::Status, window::Id) -> Option<Message>,
|
||||
) -> Subscription<Message>
|
||||
where
|
||||
Message: 'static + MaybeSend,
|
||||
|
|
@ -32,13 +32,12 @@ where
|
|||
#[derive(Hash)]
|
||||
struct EventsWith;
|
||||
|
||||
subscription::filter_map(
|
||||
(EventsWith, f),
|
||||
move |event, status| match event {
|
||||
Event::Window(_, window::Event::RedrawRequested(_)) => None,
|
||||
_ => f(event, status),
|
||||
},
|
||||
)
|
||||
subscription::filter_map((EventsWith, f), move |event, status, window| {
|
||||
match event {
|
||||
Event::Window(window::Event::RedrawRequested(_)) => None,
|
||||
_ => f(event, status, window),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Creates a [`Subscription`] that produces a message for every runtime event,
|
||||
|
|
@ -47,7 +46,7 @@ where
|
|||
/// **Warning:** This [`Subscription`], if unfiltered, may produce messages in
|
||||
/// an infinite loop.
|
||||
pub fn listen_raw<Message>(
|
||||
f: fn(Event, event::Status) -> Option<Message>,
|
||||
f: fn(Event, event::Status, window::Id) -> Option<Message>,
|
||||
) -> Subscription<Message>
|
||||
where
|
||||
Message: 'static + MaybeSend,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ where
|
|||
#[derive(Hash)]
|
||||
struct OnKeyPress;
|
||||
|
||||
subscription::filter_map((OnKeyPress, f), move |event, status| {
|
||||
subscription::filter_map((OnKeyPress, f), move |event, status, _window| {
|
||||
match (event, status) {
|
||||
(
|
||||
core::Event::Keyboard(Event::KeyPressed {
|
||||
|
|
@ -45,8 +45,9 @@ where
|
|||
#[derive(Hash)]
|
||||
struct OnKeyRelease;
|
||||
|
||||
subscription::filter_map((OnKeyRelease, f), move |event, status| {
|
||||
match (event, status) {
|
||||
subscription::filter_map(
|
||||
(OnKeyRelease, f),
|
||||
move |event, status, _window| match (event, status) {
|
||||
(
|
||||
core::Event::Keyboard(Event::KeyReleased {
|
||||
key,
|
||||
|
|
@ -56,6 +57,6 @@ where
|
|||
core::event::Status::Ignored,
|
||||
) => f(key, modifiers),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
//! Run commands and keep track of subscriptions.
|
||||
use crate::core::event::{self, Event};
|
||||
use crate::core::window;
|
||||
use crate::subscription;
|
||||
use crate::{BoxFuture, BoxStream, Executor, MaybeSend};
|
||||
|
||||
|
|
@ -127,7 +128,12 @@ where
|
|||
/// See [`Tracker::broadcast`] to learn more.
|
||||
///
|
||||
/// [`Tracker::broadcast`]: subscription::Tracker::broadcast
|
||||
pub fn broadcast(&mut self, event: Event, status: event::Status) {
|
||||
self.subscriptions.broadcast(event, status);
|
||||
pub fn broadcast(
|
||||
&mut self,
|
||||
event: Event,
|
||||
status: event::Status,
|
||||
window: window::Id,
|
||||
) {
|
||||
self.subscriptions.broadcast(event, status, window);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ mod tracker;
|
|||
pub use tracker::Tracker;
|
||||
|
||||
use crate::core::event::{self, Event};
|
||||
use crate::core::window;
|
||||
use crate::futures::{Future, Stream};
|
||||
use crate::{BoxStream, MaybeSend};
|
||||
|
||||
|
|
@ -15,7 +16,7 @@ use std::hash::Hash;
|
|||
/// A stream of runtime events.
|
||||
///
|
||||
/// It is the input of a [`Subscription`].
|
||||
pub type EventStream = BoxStream<(Event, event::Status)>;
|
||||
pub type EventStream = BoxStream<(Event, event::Status, window::Id)>;
|
||||
|
||||
/// The hasher used for identifying subscriptions.
|
||||
pub type Hasher = rustc_hash::FxHasher;
|
||||
|
|
@ -289,7 +290,9 @@ where
|
|||
pub(crate) fn filter_map<I, F, Message>(id: I, f: F) -> Subscription<Message>
|
||||
where
|
||||
I: Hash + 'static,
|
||||
F: Fn(Event, event::Status) -> Option<Message> + MaybeSend + 'static,
|
||||
F: Fn(Event, event::Status, window::Id) -> Option<Message>
|
||||
+ MaybeSend
|
||||
+ 'static,
|
||||
Message: 'static + MaybeSend,
|
||||
{
|
||||
Subscription::from_recipe(Runner {
|
||||
|
|
@ -298,8 +301,8 @@ where
|
|||
use futures::future;
|
||||
use futures::stream::StreamExt;
|
||||
|
||||
events.filter_map(move |(event, status)| {
|
||||
future::ready(f(event, status))
|
||||
events.filter_map(move |(event, status, window)| {
|
||||
future::ready(f(event, status, window))
|
||||
})
|
||||
},
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::core::event::{self, Event};
|
||||
use crate::core::window;
|
||||
use crate::subscription::{Hasher, Recipe};
|
||||
use crate::{BoxFuture, MaybeSend};
|
||||
|
||||
|
|
@ -23,7 +24,9 @@ pub struct Tracker {
|
|||
#[derive(Debug)]
|
||||
pub struct Execution {
|
||||
_cancel: futures::channel::oneshot::Sender<()>,
|
||||
listener: Option<futures::channel::mpsc::Sender<(Event, event::Status)>>,
|
||||
listener: Option<
|
||||
futures::channel::mpsc::Sender<(Event, event::Status, window::Id)>,
|
||||
>,
|
||||
}
|
||||
|
||||
impl Tracker {
|
||||
|
|
@ -139,12 +142,19 @@ impl Tracker {
|
|||
/// currently open.
|
||||
///
|
||||
/// [`Recipe::stream`]: crate::subscription::Recipe::stream
|
||||
pub fn broadcast(&mut self, event: Event, status: event::Status) {
|
||||
pub fn broadcast(
|
||||
&mut self,
|
||||
event: Event,
|
||||
status: event::Status,
|
||||
window: window::Id,
|
||||
) {
|
||||
self.subscriptions
|
||||
.values_mut()
|
||||
.filter_map(|connection| connection.listener.as_mut())
|
||||
.for_each(|listener| {
|
||||
if let Err(error) = listener.try_send((event.clone(), status)) {
|
||||
if let Err(error) =
|
||||
listener.try_send((event.clone(), status, window))
|
||||
{
|
||||
log::warn!(
|
||||
"Error sending event to subscription: {error:?}"
|
||||
);
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ use raw_window_handle::WindowHandle;
|
|||
/// In any case, this [`Subscription`] is useful to smoothly draw application-driven
|
||||
/// animations without missing any frames.
|
||||
pub fn frames() -> Subscription<Instant> {
|
||||
event::listen_raw(|event, _status| match event {
|
||||
crate::core::Event::Window(_, Event::RedrawRequested(at)) => Some(at),
|
||||
event::listen_raw(|event, _status, _window| match event {
|
||||
crate::core::Event::Window(Event::RedrawRequested(at)) => Some(at),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ where
|
|||
Some(Event::Keyboard(keyboard_event))
|
||||
}
|
||||
core::Event::Touch(touch_event) => Some(Event::Touch(touch_event)),
|
||||
core::Event::Window(_, window::Event::RedrawRequested(instant)) => {
|
||||
core::Event::Window(window::Event::RedrawRequested(instant)) => {
|
||||
Some(Event::RedrawRequested(instant))
|
||||
}
|
||||
_ => None,
|
||||
|
|
|
|||
|
|
@ -1003,14 +1003,14 @@ where
|
|||
|
||||
state.keyboard_modifiers = modifiers;
|
||||
}
|
||||
Event::Window(_, window::Event::Unfocused) => {
|
||||
Event::Window(window::Event::Unfocused) => {
|
||||
let state = state::<Renderer>(tree);
|
||||
|
||||
if let Some(focus) = &mut state.is_focused {
|
||||
focus.is_window_focused = false;
|
||||
}
|
||||
}
|
||||
Event::Window(_, window::Event::Focused) => {
|
||||
Event::Window(window::Event::Focused) => {
|
||||
let state = state::<Renderer>(tree);
|
||||
|
||||
if let Some(focus) = &mut state.is_focused {
|
||||
|
|
@ -1020,7 +1020,7 @@ where
|
|||
shell.request_redraw(window::RedrawRequest::NextFrame);
|
||||
}
|
||||
}
|
||||
Event::Window(_, window::Event::RedrawRequested(now)) => {
|
||||
Event::Window(window::Event::RedrawRequested(now)) => {
|
||||
let state = state::<Renderer>(tree);
|
||||
|
||||
if let Some(focus) = &mut state.is_focused {
|
||||
|
|
|
|||
|
|
@ -623,7 +623,6 @@ async fn run_instance<A, E, C>(
|
|||
// 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(
|
||||
window::Id::MAIN,
|
||||
window::Event::RedrawRequested(Instant::now()),
|
||||
);
|
||||
|
||||
|
|
@ -651,7 +650,11 @@ async fn run_instance<A, E, C>(
|
|||
_ => ControlFlow::Wait,
|
||||
});
|
||||
|
||||
runtime.broadcast(redraw_event, core::event::Status::Ignored);
|
||||
runtime.broadcast(
|
||||
redraw_event,
|
||||
core::event::Status::Ignored,
|
||||
window::Id::MAIN,
|
||||
);
|
||||
|
||||
debug.draw_started();
|
||||
let new_mouse_interaction = user_interface.draw(
|
||||
|
|
@ -714,7 +717,6 @@ async fn run_instance<A, E, C>(
|
|||
state.update(&window, &window_event, &mut debug);
|
||||
|
||||
if let Some(event) = conversion::window_event(
|
||||
window::Id::MAIN,
|
||||
window_event,
|
||||
state.scale_factor(),
|
||||
state.modifiers(),
|
||||
|
|
@ -742,7 +744,7 @@ async fn run_instance<A, E, C>(
|
|||
for (event, status) in
|
||||
events.drain(..).zip(statuses.into_iter())
|
||||
{
|
||||
runtime.broadcast(event, status);
|
||||
runtime.broadcast(event, status, window::Id::MAIN);
|
||||
}
|
||||
|
||||
if !messages.is_empty()
|
||||
|
|
|
|||
|
|
@ -126,7 +126,6 @@ pub fn window_attributes(
|
|||
|
||||
/// Converts a winit window event into an iced event.
|
||||
pub fn window_event(
|
||||
id: window::Id,
|
||||
event: winit::event::WindowEvent,
|
||||
scale_factor: f64,
|
||||
modifiers: winit::keyboard::ModifiersState,
|
||||
|
|
@ -137,16 +136,13 @@ pub fn window_event(
|
|||
WindowEvent::Resized(new_size) => {
|
||||
let logical_size = new_size.to_logical(scale_factor);
|
||||
|
||||
Some(Event::Window(
|
||||
id,
|
||||
window::Event::Resized {
|
||||
width: logical_size.width,
|
||||
height: logical_size.height,
|
||||
},
|
||||
))
|
||||
Some(Event::Window(window::Event::Resized {
|
||||
width: logical_size.width,
|
||||
height: logical_size.height,
|
||||
}))
|
||||
}
|
||||
WindowEvent::CloseRequested => {
|
||||
Some(Event::Window(id, window::Event::CloseRequested))
|
||||
Some(Event::Window(window::Event::CloseRequested))
|
||||
}
|
||||
WindowEvent::CursorMoved { position, .. } => {
|
||||
let position = position.to_logical::<f64>(scale_factor);
|
||||
|
|
@ -264,22 +260,19 @@ pub fn window_event(
|
|||
self::modifiers(new_modifiers.state()),
|
||||
)))
|
||||
}
|
||||
WindowEvent::Focused(focused) => Some(Event::Window(
|
||||
id,
|
||||
if focused {
|
||||
window::Event::Focused
|
||||
} else {
|
||||
window::Event::Unfocused
|
||||
},
|
||||
)),
|
||||
WindowEvent::Focused(focused) => Some(Event::Window(if focused {
|
||||
window::Event::Focused
|
||||
} else {
|
||||
window::Event::Unfocused
|
||||
})),
|
||||
WindowEvent::HoveredFile(path) => {
|
||||
Some(Event::Window(id, window::Event::FileHovered(path.clone())))
|
||||
Some(Event::Window(window::Event::FileHovered(path.clone())))
|
||||
}
|
||||
WindowEvent::DroppedFile(path) => {
|
||||
Some(Event::Window(id, window::Event::FileDropped(path.clone())))
|
||||
Some(Event::Window(window::Event::FileDropped(path.clone())))
|
||||
}
|
||||
WindowEvent::HoveredFileCancelled => {
|
||||
Some(Event::Window(id, window::Event::FilesHoveredLeft))
|
||||
Some(Event::Window(window::Event::FilesHoveredLeft))
|
||||
}
|
||||
WindowEvent::Touch(touch) => {
|
||||
Some(Event::Touch(touch_event(touch, scale_factor)))
|
||||
|
|
@ -288,7 +281,7 @@ pub fn window_event(
|
|||
let winit::dpi::LogicalPosition { x, y } =
|
||||
position.to_logical(scale_factor);
|
||||
|
||||
Some(Event::Window(id, window::Event::Moved { x, y }))
|
||||
Some(Event::Window(window::Event::Moved { x, y }))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -492,13 +492,10 @@ async fn run_instance<A, E, C>(
|
|||
let mut events = {
|
||||
vec![(
|
||||
Some(window::Id::MAIN),
|
||||
core::Event::Window(
|
||||
window::Id::MAIN,
|
||||
window::Event::Opened {
|
||||
position: main_window.position(),
|
||||
size: main_window.size(),
|
||||
},
|
||||
),
|
||||
core::Event::Window(window::Event::Opened {
|
||||
position: main_window.position(),
|
||||
size: main_window.size(),
|
||||
}),
|
||||
)]
|
||||
};
|
||||
|
||||
|
|
@ -565,13 +562,10 @@ async fn run_instance<A, E, C>(
|
|||
|
||||
events.push((
|
||||
Some(id),
|
||||
core::Event::Window(
|
||||
id,
|
||||
window::Event::Opened {
|
||||
position: window.position(),
|
||||
size: window.size(),
|
||||
},
|
||||
),
|
||||
core::Event::Window(window::Event::Opened {
|
||||
position: window.position(),
|
||||
size: window.size(),
|
||||
}),
|
||||
));
|
||||
}
|
||||
Event::EventLoopAwakened(event) => {
|
||||
|
|
@ -623,7 +617,6 @@ async fn run_instance<A, E, C>(
|
|||
// 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 = core::Event::Window(
|
||||
id,
|
||||
window::Event::RedrawRequested(Instant::now()),
|
||||
);
|
||||
|
||||
|
|
@ -665,6 +658,7 @@ async fn run_instance<A, E, C>(
|
|||
runtime.broadcast(
|
||||
redraw_event.clone(),
|
||||
core::event::Status::Ignored,
|
||||
id,
|
||||
);
|
||||
|
||||
let _ = control_sender.start_send(Control::ChangeFlow(
|
||||
|
|
@ -802,7 +796,7 @@ async fn run_instance<A, E, C>(
|
|||
|
||||
events.push((
|
||||
None,
|
||||
core::Event::Window(id, window::Event::Closed),
|
||||
core::Event::Window(window::Event::Closed),
|
||||
));
|
||||
|
||||
if window_manager.is_empty() {
|
||||
|
|
@ -816,7 +810,6 @@ async fn run_instance<A, E, C>(
|
|||
);
|
||||
|
||||
if let Some(event) = conversion::window_event(
|
||||
id,
|
||||
window_event,
|
||||
window.state.scale_factor(),
|
||||
window.state.modifiers(),
|
||||
|
|
@ -874,7 +867,7 @@ async fn run_instance<A, E, C>(
|
|||
.into_iter()
|
||||
.zip(statuses.into_iter())
|
||||
{
|
||||
runtime.broadcast(event, status);
|
||||
runtime.broadcast(event, status, id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue