diff options
| author | 2024-06-11 20:22:44 +0200 | |
|---|---|---|
| committer | 2024-06-11 20:22:44 +0200 | |
| commit | e6d0b3bda5042a1017a5944a5227c97e0ed6caf9 (patch) | |
| tree | 916f837424c3baeacc1e0f43b02bc892a3445cbb /futures | |
| parent | bda01567d59c00e42e5a208ee6d9ec4153d5c195 (diff) | |
| parent | 6ea7846d88915f8d820c5126d7757f1346234522 (diff) | |
| download | iced-e6d0b3bda5042a1017a5944a5227c97e0ed6caf9.tar.gz iced-e6d0b3bda5042a1017a5944a5227c97e0ed6caf9.tar.bz2 iced-e6d0b3bda5042a1017a5944a5227c97e0ed6caf9.zip  | |
Merge pull request #2456 from iced-rs/window-id-in-event-subscriptions
Introduce `window::Id` to `Event` subscriptions
Diffstat (limited to '')
| -rw-r--r-- | futures/src/event.rs | 54 | ||||
| -rw-r--r-- | futures/src/keyboard.rs | 39 | ||||
| -rw-r--r-- | futures/src/runtime.rs | 5 | ||||
| -rw-r--r-- | futures/src/subscription.rs | 49 | ||||
| -rw-r--r-- | futures/src/subscription/tracker.rs | 9 | 
5 files changed, 109 insertions, 47 deletions
diff --git a/futures/src/event.rs b/futures/src/event.rs index 97224506..72ea78ad 100644 --- a/futures/src/event.rs +++ b/futures/src/event.rs @@ -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,18 @@ 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| 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, @@ -47,7 +52,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, @@ -55,5 +60,32 @@ where      #[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, +    })  } diff --git a/futures/src/keyboard.rs b/futures/src/keyboard.rs index 8e7da38f..f0d7d757 100644 --- a/futures/src/keyboard.rs +++ b/futures/src/keyboard.rs @@ -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; @@ -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,      })  } @@ -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,      })  } diff --git a/futures/src/runtime.rs b/futures/src/runtime.rs index cac7b7e1..157e2c67 100644 --- a/futures/src/runtime.rs +++ b/futures/src/runtime.rs @@ -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}; @@ -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);      }  } diff --git a/futures/src/subscription.rs b/futures/src/subscription.rs index 93e35608..316fc44d 100644 --- a/futures/src/subscription.rs +++ b/futures/src/subscription.rs @@ -3,7 +3,8 @@ mod tracker;  pub use tracker::Tracker; -use crate::core::event::{self, Event}; +use crate::core::event; +use crate::core::window;  use crate::futures::{Future, Stream};  use crate::{BoxStream, MaybeSend}; @@ -12,10 +13,48 @@ use futures::never::Never;  use std::any::TypeId;  use std::hash::Hash; +/// A subscription event. +#[derive(Debug, Clone, PartialEq)] +pub enum Event { +    /// A user interacted with a user interface in a window. +    Interaction { +        /// The window holding the interface of the interaction. +        window: window::Id, +        /// The [`Event`] describing the interaction. +        /// +        /// [`Event`]: event::Event +        event: event::Event, + +        /// The [`event::Status`] of the interaction. +        status: event::Status, +    }, + +    /// 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), +} +  /// A stream of runtime events.  ///  /// It is the input of a [`Subscription`]. -pub type EventStream = BoxStream<(Event, event::Status)>; +pub type EventStream = BoxStream<Event>;  /// The hasher used for identifying subscriptions.  pub type Hasher = rustc_hash::FxHasher; @@ -289,7 +328,7 @@ 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) -> Option<Message> + MaybeSend + 'static,      Message: 'static + MaybeSend,  {      Subscription::from_recipe(Runner { @@ -298,9 +337,7 @@ where              use futures::future;              use futures::stream::StreamExt; -            events.filter_map(move |(event, status)| { -                future::ready(f(event, status)) -            }) +            events.filter_map(move |event| future::ready(f(event)))          },      })  } diff --git a/futures/src/subscription/tracker.rs b/futures/src/subscription/tracker.rs index 277a446b..f17e3ea3 100644 --- a/futures/src/subscription/tracker.rs +++ b/futures/src/subscription/tracker.rs @@ -1,5 +1,4 @@ -use crate::core::event::{self, Event}; -use crate::subscription::{Hasher, Recipe}; +use crate::subscription::{Event, Hasher, Recipe};  use crate::{BoxFuture, MaybeSend};  use futures::channel::mpsc; @@ -23,7 +22,7 @@ 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>>,  }  impl Tracker { @@ -139,12 +138,12 @@ 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) {          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()) {                      log::warn!(                          "Error sending event to subscription: {error:?}"                      );  | 
