diff --git a/crates/bevy_winit/Cargo.toml b/crates/bevy_winit/Cargo.toml index 4deff8744ed4bd..9583fde79cca40 100644 --- a/crates/bevy_winit/Cargo.toml +++ b/crates/bevy_winit/Cargo.toml @@ -24,6 +24,7 @@ bevy_input = { path = "../bevy_input", version = "0.3.0" } bevy_math = { path = "../bevy_math", version = "0.3.0" } bevy_window = { path = "../bevy_window", version = "0.3.0" } bevy_utils = { path = "../bevy_utils", version = "0.3.0" } +bevy_log = { path = "../bevy_log", version = "0.3.0" } # other winit = { version = "0.24.0", default-features = false } diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 6f80358aa6ef6c..5ef81c76576869 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -11,6 +11,7 @@ pub use winit_windows::*; use bevy_app::{prelude::*, AppExit}; use bevy_ecs::{Resources, World}; +use bevy_log::info; use bevy_math::Vec2; use bevy_utils::tracing::{error, trace}; use bevy_window::{ @@ -166,10 +167,15 @@ pub fn winit_runner(mut app: App) { trace!("Entering winit event loop"); - let should_return_from_run = app + let WinitConfig { + return_from_run: should_return_from_run, + ignore_unknown_window_id: should_ignore_unknown_window_id, + } = app .resources .get::() - .map_or(false, |config| config.return_from_run); + .as_deref() + .cloned() + .unwrap_or_default(); let event_handler = move |event: Event<()>, event_loop: &EventLoopWindowTarget<()>, @@ -187,163 +193,150 @@ pub fn winit_runner(mut app: App) { event, window_id: winit_window_id, .. - } => match event { - WindowEvent::Resized(size) => { - let winit_windows = app.resources.get_mut::().unwrap(); - let mut windows = app.resources.get_mut::().unwrap(); - let window_id = winit_windows.get_window_id(winit_window_id).unwrap(); - let window = windows.get_mut(window_id).unwrap(); - window.update_actual_size_from_backend(size.width, size.height); - let mut resize_events = - app.resources.get_mut::>().unwrap(); - resize_events.send(WindowResized { - id: window_id, - width: window.width(), - height: window.height(), - }); - } - WindowEvent::CloseRequested => { - let mut window_close_requested_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(); - window_close_requested_events.send(WindowCloseRequested { id: window_id }); - } - WindowEvent::KeyboardInput { ref input, .. } => { - let mut keyboard_input_events = - app.resources.get_mut::>().unwrap(); - keyboard_input_events.send(converters::convert_keyboard_input(input)); + } => { + let winit_windows = app.resources.get_mut::().unwrap(); + let mut windows = app.resources.get_mut::().unwrap(); + let window_id_opt = winit_windows.get_window_id(winit_window_id); + let window_opt = window_id_opt + .as_ref() + .cloned() + .and_then(|id| windows.get_mut(id)); + if should_ignore_unknown_window_id && window_opt.is_none() { + info!("Skipped event for unknown Window Id {:?}", winit_window_id); + return; } - WindowEvent::CursorMoved { position, .. } => { - let mut cursor_moved_events = - app.resources.get_mut::>().unwrap(); - let winit_windows = app.resources.get_mut::().unwrap(); - let mut windows = app.resources.get_mut::().unwrap(); - let window_id = winit_windows.get_window_id(winit_window_id).unwrap(); - let winit_window = winit_windows.get_window(window_id).unwrap(); - let window = windows.get_mut(window_id).unwrap(); - let position = position.to_logical(winit_window.scale_factor()); - let inner_size = winit_window - .inner_size() - .to_logical::(winit_window.scale_factor()); + let window = window_opt.unwrap(); + let window_id = window_id_opt.unwrap(); + match event { + WindowEvent::Resized(size) => { + window.update_actual_size_from_backend(size.width, size.height); + let mut resize_events = + app.resources.get_mut::>().unwrap(); + resize_events.send(WindowResized { + id: window_id, + width: window.width(), + height: window.height(), + }); + } + WindowEvent::CloseRequested => { + let mut window_close_requested_events = app + .resources + .get_mut::>() + .unwrap(); + window_close_requested_events.send(WindowCloseRequested { id: window_id }); + } + WindowEvent::KeyboardInput { ref input, .. } => { + let mut keyboard_input_events = + app.resources.get_mut::>().unwrap(); + keyboard_input_events.send(converters::convert_keyboard_input(input)); + } + WindowEvent::CursorMoved { position, .. } => { + let mut cursor_moved_events = + app.resources.get_mut::>().unwrap(); + let winit_window = winit_windows.get_window(window_id).unwrap(); + let position = position.to_logical(winit_window.scale_factor()); + let inner_size = winit_window + .inner_size() + .to_logical::(winit_window.scale_factor()); - // move origin to bottom left - let y_position = inner_size.height - position.y; + // move origin to bottom left + let y_position = inner_size.height - position.y; - let position = Vec2::new(position.x, y_position); - window.update_cursor_position_from_backend(Some(position)); + let position = Vec2::new(position.x, y_position); + window.update_cursor_position_from_backend(Some(position)); - cursor_moved_events.send(CursorMoved { - id: window_id, - position, - }); - } - WindowEvent::CursorEntered { .. } => { - let mut cursor_entered_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(); - cursor_entered_events.send(CursorEntered { id: window_id }); - } - WindowEvent::CursorLeft { .. } => { - let mut cursor_left_events = - app.resources.get_mut::>().unwrap(); - let winit_windows = app.resources.get_mut::().unwrap(); - let mut windows = app.resources.get_mut::().unwrap(); - let window_id = winit_windows.get_window_id(winit_window_id).unwrap(); - let window = windows.get_mut(window_id).unwrap(); - window.update_cursor_position_from_backend(None); - cursor_left_events.send(CursorLeft { id: window_id }); - } - WindowEvent::MouseInput { state, button, .. } => { - let mut mouse_button_input_events = - app.resources.get_mut::>().unwrap(); - mouse_button_input_events.send(MouseButtonInput { - button: converters::convert_mouse_button(button), - state: converters::convert_element_state(state), - }); - } - WindowEvent::MouseWheel { delta, .. } => match delta { - event::MouseScrollDelta::LineDelta(x, y) => { - let mut mouse_wheel_input_events = - app.resources.get_mut::>().unwrap(); - mouse_wheel_input_events.send(MouseWheel { - unit: MouseScrollUnit::Line, - x, - y, + cursor_moved_events.send(CursorMoved { + id: window_id, + position, }); } - event::MouseScrollDelta::PixelDelta(p) => { - let mut mouse_wheel_input_events = - app.resources.get_mut::>().unwrap(); - mouse_wheel_input_events.send(MouseWheel { - unit: MouseScrollUnit::Pixel, - x: p.x as f32, - y: p.y as f32, + WindowEvent::CursorEntered { .. } => { + let mut cursor_entered_events = + app.resources.get_mut::>().unwrap(); + cursor_entered_events.send(CursorEntered { id: window_id }); + } + WindowEvent::CursorLeft { .. } => { + let mut cursor_left_events = + app.resources.get_mut::>().unwrap(); + window.update_cursor_position_from_backend(None); + cursor_left_events.send(CursorLeft { id: window_id }); + } + WindowEvent::MouseInput { state, button, .. } => { + let mut mouse_button_input_events = + app.resources.get_mut::>().unwrap(); + mouse_button_input_events.send(MouseButtonInput { + button: converters::convert_mouse_button(button), + state: converters::convert_element_state(state), }); } - }, - WindowEvent::Touch(touch) => { - let mut touch_input_events = - app.resources.get_mut::>().unwrap(); + WindowEvent::MouseWheel { delta, .. } => match delta { + event::MouseScrollDelta::LineDelta(x, y) => { + let mut mouse_wheel_input_events = + app.resources.get_mut::>().unwrap(); + mouse_wheel_input_events.send(MouseWheel { + unit: MouseScrollUnit::Line, + x, + y, + }); + } + event::MouseScrollDelta::PixelDelta(p) => { + let mut mouse_wheel_input_events = + app.resources.get_mut::>().unwrap(); + mouse_wheel_input_events.send(MouseWheel { + unit: MouseScrollUnit::Pixel, + x: p.x as f32, + y: p.y as f32, + }); + } + }, + WindowEvent::Touch(touch) => { + let mut touch_input_events = + app.resources.get_mut::>().unwrap(); - let winit_windows = app.resources.get_mut::().unwrap(); - let windows = app.resources.get_mut::().unwrap(); - let window_id = winit_windows.get_window_id(winit_window_id).unwrap(); - let winit_window = winit_windows.get_window(window_id).unwrap(); - let mut location = touch.location.to_logical(winit_window.scale_factor()); + let winit_window = winit_windows.get_window(window_id).unwrap(); + let mut location = touch.location.to_logical(winit_window.scale_factor()); - // FIXME?: On Android window start is top while on PC/Linux/OSX on bottom - if cfg!(target_os = "android") { - let window_height = windows.get_primary().unwrap().height(); - location.y = window_height - location.y; + // FIXME?: On Android window start is top while on PC/Linux/OSX on bottom + if cfg!(target_os = "android") { + let window_height = windows.get_primary().unwrap().height(); + location.y = window_height - location.y; + } + touch_input_events.send(converters::convert_touch_input(touch, location)); } - touch_input_events.send(converters::convert_touch_input(touch, location)); - } - WindowEvent::ReceivedCharacter(c) => { - let mut char_input_events = app - .resources - .get_mut::>() - .unwrap(); + 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, - }) - } - WindowEvent::ScaleFactorChanged { - scale_factor, - new_inner_size, - } => { - let winit_windows = app.resources.get_mut::().unwrap(); - let mut windows = app.resources.get_mut::().unwrap(); - let window_id = winit_windows.get_window_id(winit_window_id).unwrap(); - let window = windows.get_mut(window_id).unwrap(); - window.update_actual_size_from_backend( - new_inner_size.width, - new_inner_size.height, - ); - window.update_scale_factor_from_backend(scale_factor); - // should we send a resize event to indicate the change in - // logical size? - } - WindowEvent::Focused(focused) => { - let mut focused_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(); - focused_events.send(WindowFocused { - id: window_id, - focused, - }); + char_input_events.send(ReceivedCharacter { + id: window_id, + char: c, + }) + } + WindowEvent::ScaleFactorChanged { + scale_factor, + new_inner_size, + } => { + window.update_actual_size_from_backend( + new_inner_size.width, + new_inner_size.height, + ); + window.update_scale_factor_from_backend(scale_factor); + // should we send a resize event to indicate the change in + // logical size? + } + WindowEvent::Focused(focused) => { + let mut focused_events = + app.resources.get_mut::>().unwrap(); + focused_events.send(WindowFocused { + id: window_id, + focused, + }); + } + _ => {} } - _ => {} - }, + } event::Event::DeviceEvent { event: DeviceEvent::MouseMotion { delta }, .. diff --git a/crates/bevy_winit/src/winit_config.rs b/crates/bevy_winit/src/winit_config.rs index 584d0b70273f83..f05f352d6393c7 100644 --- a/crates/bevy_winit/src/winit_config.rs +++ b/crates/bevy_winit/src/winit_config.rs @@ -1,5 +1,5 @@ /// A resource for configuring usage of the `rust_winit` library. -#[derive(Debug, Default)] +#[derive(Debug, Default, Clone)] pub struct WinitConfig { /// Configures the winit library to return control to the main thread after /// the [run](bevy_app::App::run) loop is exited. Winit strongly recommends @@ -12,4 +12,6 @@ pub struct WinitConfig { /// `openbsd`. If set to true on an unsupported platform /// [run](bevy_app::App::run) will panic. pub return_from_run: bool, + + pub ignore_unknown_window_id: bool, } diff --git a/examples/app/return_after_run.rs b/examples/app/return_after_run.rs index ab951341a62dc9..ac6f0d0206233b 100644 --- a/examples/app/return_after_run.rs +++ b/examples/app/return_after_run.rs @@ -5,6 +5,7 @@ fn main() { App::build() .add_resource(WinitConfig { return_from_run: true, + ..Default::default() }) .add_resource(ClearColor(Color::rgb(0.2, 0.2, 0.8))) .add_plugins(DefaultPlugins) @@ -13,6 +14,7 @@ fn main() { App::build() .add_resource(WinitConfig { return_from_run: true, + ..Default::default() }) .add_resource(ClearColor(Color::rgb(0.2, 0.8, 0.2))) .add_plugins(DefaultPlugins)