Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,11 @@ fn main() {
},
|_elwt, window| softbuffer::Surface::new(&context, window.clone()).unwrap(),
)
.with_event_handler(|window, surface, event, elwt| {
.with_event_handler(|window, surface, _, event, elwt| {
elwt.set_control_flow(ControlFlow::Wait);

match event {
Event::WindowEvent { window_id, event: WindowEvent::RedrawRequested } if window_id == window.id() => {
WindowEvent::RedrawRequested => {
let Some(surface) = surface else {
eprintln!("RedrawRequested fired before Resumed or after Suspended");
return;
Expand Down Expand Up @@ -121,10 +121,7 @@ fn main() {

buffer.present().unwrap();
}
Event::WindowEvent {
event: WindowEvent::CloseRequested,
window_id,
} if window_id == window.id() => {
WindowEvent::CloseRequested => {
elwt.exit();
}
_ => {}
Expand Down
37 changes: 14 additions & 23 deletions examples/animation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use rayon::prelude::*;
use std::f64::consts::PI;
use std::num::NonZeroU32;
use web_time::Instant;
use winit::event::{Event, KeyEvent, WindowEvent};
use winit::event::{KeyEvent, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
use winit::keyboard::{Key, NamedKey};

Expand All @@ -29,16 +29,13 @@ fn main() {
softbuffer::Surface::new(&context, window.clone()).unwrap()
},
)
.with_event_handler(move |state, surface, event, elwt| {
.with_event_handler(move |state, surface, _, event, elwt| {
let (window, old_size, frames) = state;

elwt.set_control_flow(ControlFlow::Poll);

match event {
Event::WindowEvent {
window_id,
event: WindowEvent::Resized(size),
} if window_id == window.id() => {
WindowEvent::Resized(size) => {
let Some(surface) = surface else {
eprintln!("Resized fired before Resumed or after Suspended");
return;
Expand All @@ -50,10 +47,7 @@ fn main() {
surface.resize(width, height).unwrap();
}
}
Event::WindowEvent {
window_id,
event: WindowEvent::RedrawRequested,
} if window_id == window.id() => {
WindowEvent::RedrawRequested => {
let Some(surface) = surface else {
eprintln!("RedrawRequested fired before Resumed or after Suspended");
return;
Expand All @@ -77,26 +71,23 @@ fn main() {
buffer.present().unwrap();
}
}
Event::AboutToWait => {
window.request_redraw();
}
Event::WindowEvent {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
logical_key: Key::Named(NamedKey::Escape),
..
},
KeyEvent {
logical_key: Key::Named(NamedKey::Escape),
..
},
window_id,
} if window_id == window.id() => {
..
} => {
elwt.exit();
}
_ => {}
}
})
.with_about_to_wait_handler(|state, _, _| {
let (window, _, _) = state;
window.request_redraw();
});

winit_app::run_app(event_loop, app);
Expand Down
25 changes: 9 additions & 16 deletions examples/fruit.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use image::GenericImageView;
use std::num::NonZeroU32;
use winit::event::{Event, KeyEvent, WindowEvent};
use winit::event::{KeyEvent, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
use winit::keyboard::{Key, NamedKey};

Expand Down Expand Up @@ -35,14 +35,11 @@ fn main() {
surface
},
)
.with_event_handler(move |window, surface, event, elwt| {
.with_event_handler(move |_window, surface, _, event, elwt| {
elwt.set_control_flow(ControlFlow::Wait);

match event {
Event::WindowEvent {
window_id,
event: WindowEvent::RedrawRequested,
} if window_id == window.id() => {
WindowEvent::RedrawRequested => {
let Some(surface) = surface else {
eprintln!("RedrawRequested fired before Resumed or after Suspended");
return;
Expand All @@ -61,19 +58,15 @@ fn main() {

buffer.present().unwrap();
}
Event::WindowEvent {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
logical_key: Key::Named(NamedKey::Escape),
..
},
KeyEvent {
logical_key: Key::Named(NamedKey::Escape),
..
},
window_id,
} if window_id == window.id() => {
..
} => {
elwt.exit();
}
_ => {}
Expand Down
46 changes: 16 additions & 30 deletions examples/rectangle.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::num::NonZeroU32;
use winit::event::{ElementState, Event, KeyEvent, WindowEvent};
use winit::event::{ElementState, KeyEvent, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
use winit::keyboard::{Key, NamedKey};

Expand Down Expand Up @@ -38,16 +38,13 @@ fn main() {
},
move |_elwt, (window, _flag)| softbuffer::Surface::new(&context, window.clone()).unwrap(),
)
.with_event_handler(|state, surface, event, elwt| {
.with_event_handler(|state, surface, _, event, elwt| {
let (window, flag) = state;

elwt.set_control_flow(ControlFlow::Wait);

match event {
Event::WindowEvent {
window_id,
event: WindowEvent::Resized(size),
} if window_id == window.id() => {
WindowEvent::Resized(size) => {
let Some(surface) = surface else {
eprintln!("Resized fired before Resumed or after Suspended");
return;
Expand All @@ -60,10 +57,7 @@ fn main() {
surface.resize(width, height).unwrap();
}
}
Event::WindowEvent {
window_id,
event: WindowEvent::RedrawRequested,
} if window_id == window.id() => {
WindowEvent::RedrawRequested => {
let Some(surface) = surface else {
eprintln!("RedrawRequested fired before Resumed or after Suspended");
return;
Expand All @@ -85,35 +79,27 @@ fn main() {
}
}

Event::WindowEvent {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
logical_key: Key::Named(NamedKey::Escape),
..
},
KeyEvent {
logical_key: Key::Named(NamedKey::Escape),
..
},
window_id,
} if window_id == window.id() => {
..
} => {
elwt.exit();
}

Event::WindowEvent {
WindowEvent::KeyboardInput {
event:
WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
logical_key: Key::Named(NamedKey::Space),
..
},
KeyEvent {
state: ElementState::Pressed,
logical_key: Key::Named(NamedKey::Space),
..
},
window_id,
} if window_id == window.id() => {
..
} => {
// Flip the rectangle flag and request a redraw to show the changed image
*flag = !*flag;
window.request_redraw();
Expand Down
64 changes: 41 additions & 23 deletions examples/utils/winit_app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use std::rc::Rc;

use winit::application::ApplicationHandler;
use winit::event::{Event, WindowEvent};
use winit::event::WindowEvent;
use winit::event_loop::{ActiveEventLoop, EventLoop};
use winit::window::{Window, WindowAttributes, WindowId};

Expand Down Expand Up @@ -31,7 +31,7 @@
}

/// Easily constructable winit application.
pub(crate) struct WinitApp<T, S, Init, InitSurface, Handler> {
pub(crate) struct WinitApp<T, S, Init, InitSurface, Handler, AboutToWaitHandler> {
/// Closure to initialize `state`.
init: Init,

Expand All @@ -41,6 +41,9 @@
/// Closure to run on window events.
event: Handler,

/// Closure to run on about_to_wait events.
about_to_wait: AboutToWaitHandler,

/// Contained state.
state: Option<T>,

Expand Down Expand Up @@ -75,38 +78,62 @@
}

/// Build a new application.
pub(crate) fn with_event_handler<F>(self, handler: F) -> WinitApp<T, S, Init, InitSurface, F>
pub(crate) fn with_event_handler<F>(
self,
handler: F,
) -> WinitApp<T, S, Init, InitSurface, F, impl FnMut(&mut T, Option<&mut S>, &ActiveEventLoop)>

Check failure on line 84 in examples/utils/winit_app.rs

View workflow job for this annotation

GitHub Actions / Tests (stable, i686-pc-windows-msvc, windows-latest)

very complex type used. Consider factoring parts into `type` definitions

Check failure on line 84 in examples/utils/winit_app.rs

View workflow job for this annotation

GitHub Actions / Tests (stable, x86_64-pc-windows-msvc, windows-latest)

very complex type used. Consider factoring parts into `type` definitions

Check failure on line 84 in examples/utils/winit_app.rs

View workflow job for this annotation

GitHub Actions / Tests (stable, wasm32-unknown-unknown, ubuntu-latest)

very complex type used. Consider factoring parts into `type` definitions

Check failure on line 84 in examples/utils/winit_app.rs

View workflow job for this annotation

GitHub Actions / Tests (stable, x86_64-unknown-linux-gnu, ubuntu-latest)

very complex type used. Consider factoring parts into `type` definitions

Check failure on line 84 in examples/utils/winit_app.rs

View workflow job for this annotation

GitHub Actions / Tests (stable, aarch64-apple-darwin, macos-latest)

very complex type used. Consider factoring parts into `type` definitions
where
F: FnMut(&mut T, Option<&mut S>, Event<()>, &ActiveEventLoop),
F: FnMut(&mut T, Option<&mut S>, WindowId, WindowEvent, &ActiveEventLoop),
{
WinitApp::new(self.init, self.init_surface, handler)
WinitApp::new(self.init, self.init_surface, handler, |_, _, _| {})
}
}

impl<T, S, Init, InitSurface, Handler> WinitApp<T, S, Init, InitSurface, Handler>
impl<T, S, Init, InitSurface, Handler, AboutToWaitHandler>
WinitApp<T, S, Init, InitSurface, Handler, AboutToWaitHandler>
where
Init: FnMut(&ActiveEventLoop) -> T,
InitSurface: FnMut(&ActiveEventLoop, &mut T) -> S,
Handler: FnMut(&mut T, Option<&mut S>, Event<()>, &ActiveEventLoop),
Handler: FnMut(&mut T, Option<&mut S>, WindowId, WindowEvent, &ActiveEventLoop),
AboutToWaitHandler: FnMut(&mut T, Option<&mut S>, &ActiveEventLoop),
{
/// Create a new application.
pub(crate) fn new(init: Init, init_surface: InitSurface, event: Handler) -> Self {
pub(crate) fn new(
init: Init,
init_surface: InitSurface,
event: Handler,
about_to_wait: AboutToWaitHandler,
) -> Self {
Self {
init,
init_surface,
event,
about_to_wait,
state: None,
surface_state: None,
}
}

/// Build a new application.
#[allow(dead_code)]
pub(crate) fn with_about_to_wait_handler<F>(
self,
about_to_wait: F,
) -> WinitApp<T, S, Init, InitSurface, Handler, F>
where
F: FnMut(&mut T, Option<&mut S>, &ActiveEventLoop),
{
WinitApp::new(self.init, self.init_surface, self.event, about_to_wait)
}
}

impl<T, S, Init, InitSurface, Handler> ApplicationHandler
for WinitApp<T, S, Init, InitSurface, Handler>
impl<T, S, Init, InitSurface, Handler, AboutToWaitHandler> ApplicationHandler
for WinitApp<T, S, Init, InitSurface, Handler, AboutToWaitHandler>
where
Init: FnMut(&ActiveEventLoop) -> T,
InitSurface: FnMut(&ActiveEventLoop, &mut T) -> S,
Handler: FnMut(&mut T, Option<&mut S>, Event<()>, &ActiveEventLoop),
Handler: FnMut(&mut T, Option<&mut S>, WindowId, WindowEvent, &ActiveEventLoop),
AboutToWaitHandler: FnMut(&mut T, Option<&mut S>, &ActiveEventLoop),
{
fn resumed(&mut self, el: &ActiveEventLoop) {
debug_assert!(self.state.is_none());
Expand All @@ -129,22 +156,13 @@
) {
let state = self.state.as_mut().unwrap();
let surface_state = self.surface_state.as_mut();
(self.event)(
state,
surface_state,
Event::WindowEvent { window_id, event },
event_loop,
);
(self.event)(state, surface_state, window_id, event, event_loop);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

User code compared the window_id (good practice even though we don't open multiple windows iirc). Can we do that here based on the window, or don't we have it yet (hard to tell from a phone screen, is it the sometimes-unused T generic argument)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could add a:

if window_id != window.id() {
    return;
}

branch if you want? It just seems needless IMO for single-window applications.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing so sets a good example, especially if you can do it nicely isolated in one place now? Perhaps then we no longer need to pass it into the closure, nothing seems to use it right?

}

fn about_to_wait(&mut self, event_loop: &ActiveEventLoop) {
if let Some(state) = self.state.as_mut() {
(self.event)(
state,
self.surface_state.as_mut(),
Event::AboutToWait,
event_loop,
);
let surface_state = self.surface_state.as_mut();
(self.about_to_wait)(state, surface_state, event_loop);
}
}
}
Loading
Loading