diff --git a/Cargo.toml b/Cargo.toml index 8d18c2969c90a..7a7cf6c78e9da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -236,6 +236,10 @@ path = "examples/input/keyboard_input.rs" name = "keyboard_input_events" path = "examples/input/keyboard_input_events.rs" +[[example]] +name = "char_input_events" +path = "examples/input/char_input_events.rs" + [[example]] name = "gamepad_input" path = "examples/input/gamepad_input.rs" diff --git a/crates/bevy_window/src/event.rs b/crates/bevy_window/src/event.rs index e74e614d566ee..f441bdd6f7bd5 100644 --- a/crates/bevy_window/src/event.rs +++ b/crates/bevy_window/src/event.rs @@ -40,3 +40,10 @@ pub struct CursorMoved { pub id: WindowId, pub position: Vec2, } + +/// An event that is sent whenever a window receives a character from the OS or underlying system. +#[derive(Debug, Clone)] +pub struct ReceivedCharacter { + pub id: WindowId, + pub char: char, +} diff --git a/crates/bevy_window/src/lib.rs b/crates/bevy_window/src/lib.rs index 45c81d14c712f..41d61d5bf6e64 100644 --- a/crates/bevy_window/src/lib.rs +++ b/crates/bevy_window/src/lib.rs @@ -9,7 +9,7 @@ pub use window::*; pub use windows::*; pub mod prelude { - pub use crate::{CursorMoved, Window, WindowDescriptor, Windows}; + pub use crate::{CursorMoved, ReceivedCharacter, Window, WindowDescriptor, Windows}; } use bevy_app::prelude::*; @@ -37,6 +37,7 @@ impl Plugin for WindowPlugin { .add_event::() .add_event::() .add_event::() + .add_event::() .init_resource::(); if self.add_primary_window { diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index a8c20cdb8fe8c..36eae8170d04c 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -13,7 +13,8 @@ use bevy_app::{prelude::*, AppExit}; use bevy_ecs::{IntoThreadLocalSystem, Resources, World}; use bevy_math::Vec2; use bevy_window::{ - CreateWindow, CursorMoved, Window, WindowCloseRequested, WindowCreated, WindowResized, Windows, + CreateWindow, CursorMoved, ReceivedCharacter, Window, WindowCloseRequested, WindowCreated, + WindowResized, Windows, }; use winit::{ event::{self, DeviceEvent, Event, WindowEvent}, @@ -272,6 +273,20 @@ pub fn winit_runner(mut app: App) { } touch_input_events.send(converters::convert_touch_input(touch)); } + WindowEvent::ReceivedCharacter(c) => { + let mut char_input_events = app + .resources + .get_mut::>() + .unwrap(); + + let winit_windows = app.resources.get_mut::().unwrap(); + let window_id = winit_windows.get_window_id(winit_window_id).unwrap(); + + char_input_events.send(ReceivedCharacter { + id: window_id, + char: c, + }) + } _ => {} }, event::Event::DeviceEvent { ref event, .. } => { diff --git a/examples/input/char_input_events.rs b/examples/input/char_input_events.rs new file mode 100644 index 0000000000000..207fe1c91caee --- /dev/null +++ b/examples/input/char_input_events.rs @@ -0,0 +1,23 @@ +use bevy::{prelude::*, window::ReceivedCharacter}; + +fn main() { + App::build() + .add_plugins(DefaultPlugins) + .add_system(print_char_event_system.system()) + .run(); +} + +#[derive(Default)] +struct State { + event_reader: EventReader, +} + +/// This system prints out all char events as they come in +fn print_char_event_system( + mut state: Local, + char_input_events: Res>, +) { + for event in state.event_reader.iter(&char_input_events) { + println!("{:?}: '{}'", event, event.char); + } +}