Skip to content

Commit 0606734

Browse files
bevy_winit(emit raw winit events)
1 parent d96a9d1 commit 0606734

File tree

2 files changed

+39
-10
lines changed

2 files changed

+39
-10
lines changed

crates/bevy_winit/src/lib.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ extern crate alloc;
1717
use bevy_derive::Deref;
1818
use bevy_window::{RawHandleWrapperHolder, WindowEvent};
1919
use core::marker::PhantomData;
20-
use winit::event_loop::EventLoop;
20+
use winit::{event_loop::EventLoop, window::WindowId};
2121

2222
use bevy_a11y::AccessibilityRequested;
2323
use bevy_app::{App, Last, Plugin};
@@ -117,6 +117,7 @@ impl<T: Event> Plugin for WinitPlugin<T> {
117117
app.init_non_send_resource::<WinitWindows>()
118118
.init_resource::<WinitMonitors>()
119119
.init_resource::<WinitSettings>()
120+
.add_event::<RawWinitWindowEvent>()
120121
.set_runner(winit_runner::<T>)
121122
.add_systems(
122123
Last,
@@ -149,6 +150,21 @@ impl<T: Event> Plugin for WinitPlugin<T> {
149150
#[derive(Debug, Default, Clone, Copy, Event)]
150151
pub struct WakeUp;
151152

153+
/// The original window event as produced by winit. This is meant as an escape
154+
/// hatch for power users that wish add custom winit integrations.
155+
/// If you want to process events for your app or game, you should instead use
156+
/// `bevy::window::WindowEvent`, or one of its sub-events.
157+
///
158+
/// When you receive this event it has already been handled by Bevy's main loop.
159+
/// Sending these events will NOT cause them to be processed by Bevy.
160+
#[derive(Debug, Clone, Event)]
161+
pub struct RawWinitWindowEvent {
162+
/// The window for which the event was fired.
163+
pub window_id: WindowId,
164+
/// The raw winit window event.
165+
pub event: winit::event::WindowEvent,
166+
}
167+
152168
/// A wrapper type around [`winit::event_loop::EventLoopProxy`] with the specific
153169
/// [`winit::event::Event::UserEvent`] used in the [`WinitPlugin`].
154170
///

crates/bevy_winit/src/state.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ use crate::{
4646
accessibility::AccessKitAdapters,
4747
converters, create_windows,
4848
system::{create_monitors, CachedWindow},
49-
AppSendEvent, CreateMonitorParams, CreateWindowParams, EventLoopProxyWrapper, UpdateMode,
50-
WinitSettings, WinitWindows,
49+
AppSendEvent, CreateMonitorParams, CreateWindowParams, EventLoopProxyWrapper,
50+
RawWinitWindowEvent, UpdateMode, WinitSettings, WinitWindows,
5151
};
5252

5353
/// Persistent state that is used to run the [`App`] according to the current
@@ -80,6 +80,8 @@ struct WinitAppRunnerState<T: Event> {
8080
previous_lifecycle: AppLifecycle,
8181
/// Bevy window events to send
8282
bevy_window_events: Vec<bevy_window::WindowEvent>,
83+
/// Raw Winit window events to send
84+
raw_winit_events: Vec<RawWinitWindowEvent>,
8385
_marker: PhantomData<T>,
8486

8587
event_writer_system_state: SystemState<(
@@ -121,6 +123,7 @@ impl<T: Event> WinitAppRunnerState<T> {
121123
// 3 seems to be enough, 5 is a safe margin
122124
startup_forced_updates: 5,
123125
bevy_window_events: Vec::new(),
126+
raw_winit_events: Vec::new(),
124127
_marker: PhantomData,
125128
event_writer_system_state,
126129
}
@@ -250,6 +253,12 @@ impl<T: Event> ApplicationHandler<T> for WinitAppRunnerState<T> {
250253
return;
251254
};
252255

256+
// Store a copy of the event to send to an EventWriter later.
257+
self.raw_winit_events.push(RawWinitWindowEvent {
258+
window_id,
259+
event: event.clone(),
260+
});
261+
253262
// Allow AccessKit to respond to `WindowEvent`s before they reach
254263
// the engine.
255264
if let Some(adapter) = access_kit_adapters.get_mut(&window) {
@@ -687,14 +696,16 @@ impl<T: Event> WinitAppRunnerState<T> {
687696
}
688697

689698
fn forward_bevy_events(&mut self) {
699+
let raw_winit_events = self.raw_winit_events.drain(..).collect::<Vec<_>>();
690700
let buffered_events = self.bevy_window_events.drain(..).collect::<Vec<_>>();
701+
let world = self.world_mut();
691702

692-
if buffered_events.is_empty() {
693-
return;
703+
if !raw_winit_events.is_empty() {
704+
world
705+
.resource_mut::<Events<RawWinitWindowEvent>>()
706+
.send_batch(raw_winit_events);
694707
}
695708

696-
let world = self.world_mut();
697-
698709
for winit_event in buffered_events.iter() {
699710
match winit_event.clone() {
700711
BevyWindowEvent::AppLifecycle(e) => {
@@ -781,9 +792,11 @@ impl<T: Event> WinitAppRunnerState<T> {
781792
}
782793
}
783794

784-
world
785-
.resource_mut::<Events<BevyWindowEvent>>()
786-
.send_batch(buffered_events);
795+
if !buffered_events.is_empty() {
796+
world
797+
.resource_mut::<Events<BevyWindowEvent>>()
798+
.send_batch(buffered_events);
799+
}
787800
}
788801

789802
#[cfg(feature = "custom_cursor")]

0 commit comments

Comments
 (0)