Skip to content

Commit

Permalink
Add option to ignore events when receving unknown WindowId
Browse files Browse the repository at this point in the history
  • Loading branch information
refnil committed Dec 15, 2020
1 parent 51650f1 commit 3557127
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 142 deletions.
1 change: 1 addition & 0 deletions crates/bevy_winit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
275 changes: 134 additions & 141 deletions crates/bevy_winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub use winit_windows::*;
use bevy_app::{prelude::*, AppExit};
use bevy_ecs::{Resources, World};
use bevy_math::Vec2;
use bevy_log::info;
use bevy_utils::tracing::{error, trace};
use bevy_window::{
CreateWindow, CursorEntered, CursorLeft, CursorMoved, ReceivedCharacter, WindowCloseRequested,
Expand Down Expand Up @@ -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::<WinitConfig>()
.map_or(false, |config| config.return_from_run);
.as_deref()
.cloned()
.unwrap_or_default();

let event_handler = move |event: Event<()>,
event_loop: &EventLoopWindowTarget<()>,
Expand All @@ -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::<WinitWindows>().unwrap();
let mut windows = app.resources.get_mut::<Windows>().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::<Events<WindowResized>>().unwrap();
resize_events.send(WindowResized {
id: window_id,
} => {
let winit_windows = app.resources.get_mut::<WinitWindows>().unwrap();
let mut windows = app.resources.get_mut::<Windows>().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;
}
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::<Events<WindowResized>>().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::<Events<WindowCloseRequested>>()
.unwrap();
let winit_windows = app.resources.get_mut::<WinitWindows>().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::<Events<KeyboardInput>>().unwrap();
keyboard_input_events.send(converters::convert_keyboard_input(input));
}
WindowEvent::CursorMoved { position, .. } => {
let mut cursor_moved_events =
app.resources.get_mut::<Events<CursorMoved>>().unwrap();
let winit_windows = app.resources.get_mut::<WinitWindows>().unwrap();
let mut windows = app.resources.get_mut::<Windows>().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::<f32>(winit_window.scale_factor());
});
}
WindowEvent::CloseRequested => {
let mut window_close_requested_events = app
.resources
.get_mut::<Events<WindowCloseRequested>>()
.unwrap();
window_close_requested_events.send(WindowCloseRequested { id: window_id });
}
WindowEvent::KeyboardInput { ref input, .. } => {
let mut keyboard_input_events =
app.resources.get_mut::<Events<KeyboardInput>>().unwrap();
keyboard_input_events.send(converters::convert_keyboard_input(input));
}
WindowEvent::CursorMoved { position, .. } => {
let mut cursor_moved_events =
app.resources.get_mut::<Events<CursorMoved>>().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::<f32>(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::<Events<CursorEntered>>().unwrap();
let winit_windows = app.resources.get_mut::<WinitWindows>().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::<Events<CursorLeft>>().unwrap();
let winit_windows = app.resources.get_mut::<WinitWindows>().unwrap();
let mut windows = app.resources.get_mut::<Windows>().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::<Events<MouseButtonInput>>().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::<Events<MouseWheel>>().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::<Events<MouseWheel>>().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::<Events<CursorEntered>>().unwrap();
cursor_entered_events.send(CursorEntered { id: window_id });
}
WindowEvent::CursorLeft { .. } => {
let mut cursor_left_events =
app.resources.get_mut::<Events<CursorLeft>>().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::<Events<MouseButtonInput>>().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::<Events<TouchInput>>().unwrap();
WindowEvent::MouseWheel { delta, .. } => match delta {
event::MouseScrollDelta::LineDelta(x, y) => {
let mut mouse_wheel_input_events =
app.resources.get_mut::<Events<MouseWheel>>().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::<Events<MouseWheel>>().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::<Events<TouchInput>>().unwrap();

let winit_windows = app.resources.get_mut::<WinitWindows>().unwrap();
let windows = app.resources.get_mut::<Windows>().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") {
// 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;
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::<Events<ReceivedCharacter>>()
.unwrap();

let winit_windows = app.resources.get_mut::<WinitWindows>().unwrap();
let window_id = winit_windows.get_window_id(winit_window_id).unwrap();
WindowEvent::ReceivedCharacter(c) => {
let mut char_input_events = app
.resources
.get_mut::<Events<ReceivedCharacter>>()
.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::<WinitWindows>().unwrap();
let mut windows = app.resources.get_mut::<Windows>().unwrap();
let window_id = winit_windows.get_window_id(winit_window_id).unwrap();
let window = windows.get_mut(window_id).unwrap();
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);
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::<Events<WindowFocused>>().unwrap();
focused_events.send(WindowFocused {
id: window_id,
focused,
});
}
_ => {}
}
WindowEvent::Focused(focused) => {
let mut focused_events =
app.resources.get_mut::<Events<WindowFocused>>().unwrap();
let winit_windows = app.resources.get_mut::<WinitWindows>().unwrap();
let window_id = winit_windows.get_window_id(winit_window_id).unwrap();
focused_events.send(WindowFocused {
id: window_id,
focused,
});
}
_ => {}
},
}
event::Event::DeviceEvent {
event: DeviceEvent::MouseMotion { delta },
..
Expand Down
4 changes: 3 additions & 1 deletion crates/bevy_winit/src/winit_config.rs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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,
}
2 changes: 2 additions & 0 deletions examples/app/return_after_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down

0 comments on commit 3557127

Please sign in to comment.