owned this note
owned this note
Published
Linked with GitHub
# Winit meeting
Date: 2024-01-26T14:00:00Z (UTC)
Attended: @madsmtm, @daxpedda, @kchibisov
Last meeting notes: <https://hackmd.io/vvcTgQEmTIa8nyPR8vxJ_w>
## Organizational
Make these HackMDs public, at least post on Matrix? Should we keep a historic account of meeting notes? @madsmtm has created an account, so they're at least stored there now (also, you don't seem to be able to change the title without an account).
- Should we even use HackMD? Are there better tools for this kind of stuff? Google Docs?
- How much should we use Discord? (Ideally not for anything other than the call, )
- Conclusion: Post HackMDs on Matrix before the call.
- (Optional?) Post summary on github discussions in a thread for meetings.
How are the meeting notes as laid out here? Are they fine, or should we do something else?
- They're fine.
Move more discussion to GitHub, but inside `winit` repo, not `winit-next`.
- Communicate [upgrade plan](https://hackmd.io/vvcTgQEmTIa8nyPR8vxJ_w#Upgrade-plan) for everyone to follow along, probably on <https://github.com/rust-windowing/winit/issues/3367>.
- Document weekly meetings and core team _somewhere_.
Communicate bigger changes in changelog.
- Example of how docs are done right https://docs.rs/winnow/
- Move changelog to docs.rs (cargo doc as well)?
Are GitHub Discussions worth it? To me, it just seems like two places to have issues...
- Useful for user questions.
- Maybe move user questions inside issues to discussions?
- Postponed to later
## User communication
What's the best way to communicate why `v0.30` changes are to be had? A new GitHub issue/discussion that outlines the reasoning and migration steps, and then users can comment there why their use-case doesn't work with the new design? Or note this in the changelog, and encourage users to open new issues for each complaint? I think having an existing issue is lower-friction for feedback.
- Open issue for 0.30 planning and pin it(and make it accesible for maintainers only, how it was done for 0.29), and also link to discussion thread for users to ask/complain.
Draft text for the trait rework at the bottom, other big changes will need a similar thing.
## Event handling and hooks
`tracing-subscriber` and why that doesn't work?
<https://matrix.to/#/!DGpLzJTRzBDTwZiogk:matrix.org/$M2KtcQIpR0OMKpf_Z2HiTFbei-VgoRuwMrxhfXereoc?via=matrix.org&via=ralith.com&via=mozilla.org>
Maybe trait that is used both for users and subscribers.
```rust
impl ApplicationHandler for EguiContext {
...
}
impl ApplicationHandler for App {
...
}
let mut state = ...;
event_loop.run(|runner| {
// This closure is run on every event.
// subscriber
if runner.run(&mut state.egui_context) {
// event was consumed
return
}
// user
runner.run(&mut state.app);
});
// Internally
struct BackendState {
winit: Winit,
runner: Box<Fn(Runner)>
}
// Called when I get an event from Wayland connection.
fn resize(&mut self, window_id: WindowId, new_size: Size) {
user_state = &mut state.app;
user_state.resize(&mut state.winit, window_id, new_size);
// Push back to event_sink: Vec<Event>.
let mut new_size = None;
self.runner.call(|app: &mut dyn ApplicationHandler| {
new_size = Some(app.resize(window_id));
});
}
```
Make sure you can always just not return anything, and just have some default behaviour? Are there methods that will be required?
Events with special default behaviour:
- CloseRequested: Deny closing?
- Scaling Wayland: ?
#### Meeting stopped around here ####
<hr>
Other idea:
```rust
// (ab)use type-system magic to use closures and avoid implementing a trait
struct App {
// ... state
}
event_loop
.with_state(App { ... })
.on_wakeup(|state, active, start_cause| {
match start_cause {
// ...
}
})
.on_window_event(|state, active, window_id, event| {
match event {
// ...
}
})
.run()?;
```
## Dropping `Window`
[#3317](https://github.com/rust-windowing/winit/issues/3317)
## @madsmtm's GitHub nitpicking
Get rid of the [Testers and Contributors table](https://github.com/rust-windowing/winit/wiki/Testers-and-Contributors), and the wiki in general.
Get rid of `FEATURES.md`, replace with a section in the `README.md` that documents the intended scope only.
Add [issue templates](https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/about-issue-and-pull-request-templates) so we don't have to waste time asking users which platform they're using.
---
---
Will need to be adjusted once [#3386](https://github.com/rust-windowing/winit/pull/3386) lands.
# We're changing Winit's event loop callback
Hey everyone!
There are some big changes in Winit `v0.30` that are going to affect you.
In particular, we're changing the event loop callback from a closure to a trait-based system. This is done in anticipation of [further design changes](https://github.com/rust-windowing/winit/issues/3367), but will primarily enable you to return values back to the event loop - which in turn will allow us to correctly implement oft-requested features like clipboard access, drag and drop, better IME, and so on.
## Migration
The migration _should_ be fairly straightforward, although it will probably take a bit of time and manual work.
The key change is that instead of `event_loop.run` taking a closure, you must now create a new type that implements the `ApplicationHandler` trait, and which contains the state that was previously implicit in the closure, see the following code example.
```rust
// Before
let mut click_counter = 0;
let mut window = None;
event_loop.run(|event, window_target| {
dbg!(event);
match event {
Event::NewEvents(StartCause::Init) => {
window = Some(Window::new().build(window_target));
}
Event::WindowEvent { event, window_id } => {
match event {
WindowEvent::MouseInput { state: ElementState::Pressed, button: MouseButton::Left, .. } => {
self.click_counter += 1;
if let Some(window) = window.as_ref() {
window.set_title(format!("clicked {click_counter} times"));
}
}
_ => {
// .. handle other window events
}
}
}
_ => {
// .. handle other events
}
}
})?;
// After
struct App {
my_counter: i32,
window: Option<Window>,
}
impl App for ApplicationHandler {
fn all_events_hook(&mut self, active: ActiveEventLoop<'_>, event: &Event) {
dbg!(event);
}
fn wakeup(&mut self, active: ActiveEventLoop<'_>, start_cause: StartCause) {
if let StartCause::Init = start_cause {
self.window = Some(active.create_window(WindowAttributes::new()));
}
}
fn window_event(
&mut self,
active: ActiveEventLoop<'_>,
window_id: WindowId,
event: WindowEvent,
) {
match event {
WindowEvent::MouseInput { state: ElementState::Pressed, button: MouseButton::Left, .. } => {
self.click_counter += 1;
if let Some(window) = self.window.as_ref() {
window.set_title(format!("clicked {} times", self.click_counter));
}
}
_ => {
// .. handle other window events
}
}
}
// .. handle other events
}
event_loop.run(App {
click_counter: 0,
window: None,
})?;
```
## Feedback
If you run into any problems with migrating, please feel free to submit feedback on this issue, especially if you have use-cases that are not possible, or are more difficult to do with the new design.