diff --git a/core/src/keyboard/key.rs b/core/src/keyboard/key.rs index 5a1cd9ce..7e313794 100644 --- a/core/src/keyboard/key.rs +++ b/core/src/keyboard/key.rs @@ -65,7 +65,7 @@ impl Key { let mut chars = s.chars(); let c = chars.next()?; - if chars.next().is_none() && c <= '\u{ff}' { + if chars.next().is_none() && c < '\u{370}' { return Some(c); } diff --git a/devtools/src/lib.rs b/devtools/src/lib.rs index 6ad7ae9a..4c1271cf 100644 --- a/devtools/src/lib.rs +++ b/devtools/src/lib.rs @@ -381,11 +381,13 @@ where program.subscription(&self.state).map(Event::Program); debug::subscriptions_tracked(subscription.units()); - let hotkeys = - futures::keyboard::on_key_press(|key, _modifiers| match key { - keyboard::Key::Named(keyboard::key::Named::F12) => { - Some(Message::ToggleComet) - } + let hotkeys = futures::keyboard::listen() + .filter_map(|event| match event { + keyboard::Event::KeyPressed { + modified_key: + keyboard::Key::Named(keyboard::key::Named::F12), + .. + } => Some(Message::ToggleComet), _ => None, }) .map(Event::Message); diff --git a/examples/layout/src/main.rs b/examples/layout/src/main.rs index 4907f5a4..07791796 100644 --- a/examples/layout/src/main.rs +++ b/examples/layout/src/main.rs @@ -58,12 +58,25 @@ impl Layout { fn subscription(&self) -> Subscription { use keyboard::key; - keyboard::on_key_release(|key, _modifiers| match key { - keyboard::Key::Named(key::Named::ArrowLeft) => { - Some(Message::Previous) + keyboard::listen().filter_map(|event| { + let keyboard::Event::KeyPressed { + modified_key, + repeat: false, + .. + } = event + else { + return None; + }; + + match modified_key { + keyboard::Key::Named(key::Named::ArrowLeft) => { + Some(Message::Previous) + } + keyboard::Key::Named(key::Named::ArrowRight) => { + Some(Message::Next) + } + _ => None, } - keyboard::Key::Named(key::Named::ArrowRight) => Some(Message::Next), - _ => None, }) } diff --git a/examples/pane_grid/src/main.rs b/examples/pane_grid/src/main.rs index f94e83ca..0c0f7d7c 100644 --- a/examples/pane_grid/src/main.rs +++ b/examples/pane_grid/src/main.rs @@ -117,12 +117,17 @@ impl Example { } fn subscription(&self) -> Subscription { - keyboard::on_key_press(|key_code, modifiers| { + keyboard::listen().filter_map(|event| { + let keyboard::Event::KeyPressed { key, modifiers, .. } = event + else { + return None; + }; + if !modifiers.command() { return None; } - handle_hotkey(key_code) + handle_hotkey(key) }) } diff --git a/examples/screenshot/src/main.rs b/examples/screenshot/src/main.rs index 86827858..b99157ea 100644 --- a/examples/screenshot/src/main.rs +++ b/examples/screenshot/src/main.rs @@ -227,8 +227,12 @@ impl Example { fn subscription(&self) -> Subscription { use keyboard::key; - keyboard::on_key_press(|key, _modifiers| { - if let keyboard::Key::Named(key::Named::F5) = key { + keyboard::listen().filter_map(|event| { + if let keyboard::Event::KeyPressed { + modified_key: keyboard::Key::Named(key::Named::F5), + .. + } = event + { Some(Message::Screenshot) } else { None diff --git a/examples/stopwatch/src/main.rs b/examples/stopwatch/src/main.rs index 9488f55a..c3beb338 100644 --- a/examples/stopwatch/src/main.rs +++ b/examples/stopwatch/src/main.rs @@ -65,13 +65,14 @@ impl Stopwatch { } }; - fn handle_hotkey( - key: keyboard::Key, - _modifiers: keyboard::Modifiers, - ) -> Option { + fn handle_hotkey(event: keyboard::Event) -> Option { use keyboard::key; - match key.as_ref() { + let keyboard::Event::KeyPressed { modified_key, .. } = event else { + return None; + }; + + match modified_key.as_ref() { keyboard::Key::Named(key::Named::Space) => { Some(Message::Toggle) } @@ -80,7 +81,10 @@ impl Stopwatch { } } - Subscription::batch(vec![tick, keyboard::on_key_press(handle_hotkey)]) + Subscription::batch(vec![ + tick, + keyboard::listen().filter_map(handle_hotkey), + ]) } fn view(&self) -> Element<'_, Message> { diff --git a/examples/styling/src/main.rs b/examples/styling/src/main.rs index 762657f9..fe10e4b7 100644 --- a/examples/styling/src/main.rs +++ b/examples/styling/src/main.rs @@ -190,18 +190,26 @@ impl Styling { } fn subscription(&self) -> Subscription { - keyboard::on_key_press(|key, _modifiers| match key { - keyboard::Key::Named( - keyboard::key::Named::ArrowUp | keyboard::key::Named::ArrowLeft, - ) => Some(Message::PreviousTheme), - keyboard::Key::Named( + keyboard::listen().filter_map(|event| { + let keyboard::Event::KeyPressed { + modified_key: keyboard::Key::Named(modified_key), + repeat: false, + .. + } = event + else { + return None; + }; + + match modified_key { + keyboard::key::Named::ArrowUp + | keyboard::key::Named::ArrowLeft => { + Some(Message::PreviousTheme) + } keyboard::key::Named::ArrowDown - | keyboard::key::Named::ArrowRight, - ) => Some(Message::NextTheme), - keyboard::Key::Named(keyboard::key::Named::Space) => { - Some(Message::ClearTheme) + | keyboard::key::Named::ArrowRight => Some(Message::NextTheme), + keyboard::key::Named::Space => Some(Message::ClearTheme), + _ => None, } - _ => None, }) } diff --git a/examples/todos/src/main.rs b/examples/todos/src/main.rs index 06fe11d1..34f86a91 100644 --- a/examples/todos/src/main.rs +++ b/examples/todos/src/main.rs @@ -254,12 +254,12 @@ impl Todos { fn subscription(&self) -> Subscription { use keyboard::key; - keyboard::on_key_press(|key, modifiers| { - let keyboard::Key::Named(key) = key else { - return None; - }; - - match (key, modifiers) { + keyboard::listen().filter_map(|event| match event { + keyboard::Event::KeyPressed { + key: keyboard::Key::Named(key), + modifiers, + .. + } => match (key, modifiers) { (key::Named::Tab, _) => Some(Message::TabPressed { shift: modifiers.shift(), }), @@ -270,7 +270,8 @@ impl Todos { Some(Message::ToggleFullscreen(window::Mode::Windowed)) } _ => None, - } + }, + _ => None, }) } } diff --git a/futures/src/keyboard.rs b/futures/src/keyboard.rs index 036edb9c..06e7a9db 100644 --- a/futures/src/keyboard.rs +++ b/futures/src/keyboard.rs @@ -1,56 +1,18 @@ //! Listen to keyboard events. -use crate::MaybeSend; use crate::core; -use crate::core::event; -use crate::core::keyboard::{Event, Key, Modifiers}; +use crate::core::keyboard::Event; use crate::subscription::{self, Subscription}; -/// Listens to keyboard key presses and calls the given function -/// to map them into actual messages. -/// -/// If the function returns `None`, the key press will be simply -/// ignored. -pub fn on_key_press( - f: fn(Key, Modifiers) -> Option, -) -> Subscription -where - Message: MaybeSend + 'static, -{ +/// Returns a [`Subscription`] that listens to ignored keyboard events. +pub fn listen() -> Subscription { #[derive(Hash)] - struct OnKeyPress; + struct Listen; - subscription::filter_map((OnKeyPress, f), move |event| match event { + subscription::filter_map(Listen, move |event| match event { subscription::Event::Interaction { - event: - core::Event::Keyboard(Event::KeyPressed { key, modifiers, .. }), - status: event::Status::Ignored, + event: core::Event::Keyboard(event), .. - } => f(key, modifiers), - _ => None, - }) -} - -/// Listens to keyboard key releases and calls the given function -/// to map them into actual messages. -/// -/// If the function returns `None`, the key release will be simply -/// ignored. -pub fn on_key_release( - f: fn(Key, Modifiers) -> Option, -) -> Subscription -where - Message: MaybeSend + 'static, -{ - #[derive(Hash)] - struct OnKeyRelease; - - 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), + } => Some(event), _ => None, }) } diff --git a/src/lib.rs b/src/lib.rs index 111c25e7..27561f2a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -368,8 +368,8 @@ //! visible widgets of your user interface, at every moment. //! //! As with tasks, some modules expose convenient functions that build a [`Subscription`] for you—like -//! [`time::every`] which can be used to listen to time, or [`keyboard::on_key_press`] which will notify you -//! of any key presses. But you can also create your own with [`Subscription::run`] and [`run_with`]. +//! [`time::every`] which can be used to listen to time, or [`keyboard::listen`] which will notify you +//! of any keyboard events. But you can also create your own with [`Subscription::run`] and [`run_with`]. //! //! [`run_with`]: Subscription::run_with //! @@ -590,7 +590,7 @@ pub mod keyboard { //! Listen and react to keyboard events. pub use crate::core::keyboard::key; pub use crate::core::keyboard::{Event, Key, Location, Modifiers}; - pub use iced_futures::keyboard::{on_key_press, on_key_release}; + pub use iced_futures::keyboard::listen; } pub mod mouse {