Skip to content

Commit

Permalink
Merge pull request #2456 from iced-rs/window-id-in-event-subscriptions
Browse files Browse the repository at this point in the history
Introduce `window::Id` to `Event` subscriptions
  • Loading branch information
hecrj committed Jun 11, 2024
2 parents bda0156 + 6ea7846 commit e6d0b3b
Show file tree
Hide file tree
Showing 25 changed files with 225 additions and 198 deletions.
23 changes: 1 addition & 22 deletions core/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,10 @@ pub enum Event {
Mouse(mouse::Event),

/// A window event
Window(window::Id, window::Event),
Window(window::Event),

/// A touch event
Touch(touch::Event),

/// A platform specific event
PlatformSpecific(PlatformSpecific),
}

/// A platform specific event
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum PlatformSpecific {
/// A MacOS specific event
MacOS(MacOS),
}

/// Describes an event specific to MacOS
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MacOS {
/// Triggered when the app receives an URL from the system
///
/// _**Note:** For this event to be triggered, the executable needs to be properly [bundled]!_
///
/// [bundled]: https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html#//apple_ref/doc/uid/10000123i-CH101-SW19
ReceivedUrl(String),
}

/// The status of an [`Event`] after being processed.
Expand Down
5 changes: 2 additions & 3 deletions examples/events/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down
2 changes: 0 additions & 2 deletions examples/integration/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion examples/loading_spinners/src/circular.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion examples/loading_spinners/src/linear.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
12 changes: 7 additions & 5 deletions examples/multi_window/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 1 addition & 3 deletions examples/toast/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
17 changes: 5 additions & 12 deletions examples/url_handler/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use iced::event::{self, Event};
use iced::event;
use iced::widget::{center, text};
use iced::{Element, Subscription};

Expand All @@ -15,27 +15,20 @@ struct App {

#[derive(Debug, Clone)]
enum Message {
EventOccurred(Event),
UrlReceived(String),
}

impl App {
fn update(&mut self, message: Message) {
match message {
Message::EventOccurred(event) => {
if let Event::PlatformSpecific(
event::PlatformSpecific::MacOS(event::MacOS::ReceivedUrl(
url,
)),
) = event
{
self.url = Some(url);
}
Message::UrlReceived(url) => {
self.url = Some(url);
}
}
}

fn subscription(&self) -> Subscription<Message> {
event::listen().map(Message::EventOccurred)
event::listen_url().map(Message::UrlReceived)
}

fn view(&self) -> Element<Message> {
Expand Down
4 changes: 2 additions & 2 deletions examples/visible_bounds/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
54 changes: 43 additions & 11 deletions futures/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
})
Expand All @@ -24,21 +24,26 @@ 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,
{
#[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| match event {
subscription::Event::Interaction {
event: Event::Window(window::Event::RedrawRequested(_)),
..
}
| subscription::Event::PlatformSpecific(_) => None,
subscription::Event::Interaction {
window,
event,
status,
} => f(event, status, window),
})
}

/// Creates a [`Subscription`] that produces a message for every runtime event,
Expand All @@ -47,13 +52,40 @@ 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,
{
#[derive(Hash)]
struct RawEvents;

subscription::filter_map((RawEvents, f), f)
subscription::filter_map((RawEvents, f), move |event| match event {
subscription::Event::Interaction {
window,
event,
status,
} => f(event, status, window),
subscription::Event::PlatformSpecific(_) => None,
})
}

/// Creates a [`Subscription`] that notifies of custom application URL
/// received from the system.
///
/// _**Note:** Currently, it only triggers on macOS and the executable needs to be properly [bundled]!_
///
/// [bundled]: https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html#//apple_ref/doc/uid/10000123i-CH101-SW19
pub fn listen_url() -> Subscription<String> {
#[derive(Hash)]
struct ListenUrl;

subscription::filter_map(ListenUrl, move |event| match event {
subscription::Event::PlatformSpecific(
subscription::PlatformSpecific::MacOS(
subscription::MacOS::ReceivedUrl(url),
),
) => Some(url),
_ => None,
})
}
39 changes: 17 additions & 22 deletions futures/src/keyboard.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Listen to keyboard events.
use crate::core;
use crate::core::event;
use crate::core::keyboard::{Event, Key, Modifiers};
use crate::subscription::{self, Subscription};
use crate::MaybeSend;
Expand All @@ -18,16 +19,14 @@ where
#[derive(Hash)]
struct OnKeyPress;

subscription::filter_map((OnKeyPress, f), move |event, status| {
match (event, status) {
(
core::Event::Keyboard(Event::KeyPressed {
key, modifiers, ..
}),
core::event::Status::Ignored,
) => f(key, modifiers),
_ => None,
}
subscription::filter_map((OnKeyPress, f), move |event| match event {
subscription::Event::Interaction {
event:
core::Event::Keyboard(Event::KeyPressed { key, modifiers, .. }),
status: event::Status::Ignored,
..
} => f(key, modifiers),
_ => None,
})
}

Expand All @@ -45,17 +44,13 @@ where
#[derive(Hash)]
struct OnKeyRelease;

subscription::filter_map((OnKeyRelease, f), move |event, status| {
match (event, status) {
(
core::Event::Keyboard(Event::KeyReleased {
key,
modifiers,
..
}),
core::event::Status::Ignored,
) => f(key, modifiers),
_ => None,
}
subscription::filter_map((OnKeyRelease, f), move |event| match event {
subscription::Event::Interaction {
event:
core::Event::Keyboard(Event::KeyReleased { key, modifiers, .. }),
status: event::Status::Ignored,
..
} => f(key, modifiers),
_ => None,
})
}
5 changes: 2 additions & 3 deletions futures/src/runtime.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//! Run commands and keep track of subscriptions.
use crate::core::event::{self, Event};
use crate::subscription;
use crate::{BoxFuture, BoxStream, Executor, MaybeSend};

Expand Down Expand Up @@ -127,7 +126,7 @@ 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: subscription::Event) {
self.subscriptions.broadcast(event);
}
}
Loading

0 comments on commit e6d0b3b

Please sign in to comment.