---
# System prepended metadata

title: Winit meeting 2024-02-02

---

# Winit meeting

Date: 2024-02-02T14:00:00Z (UTC)

Attended: @madsmtm, @kchibisov, @daxpedda

Last meeting notes: <https://hackmd.io/HF1SDQHhSoK9jFw0WHDS6g>


## Organizational

I'm very good at making PRs and then forgetting about them, and I've confused myself about the current state?
- I think we're doing https://github.com/rust-windowing/winit/pull/3299 combined with https://github.com/rust-windowing/winit/pull/3400 in https://github.com/rust-windowing/winit/pull/3447, right? Yes, that's right.
- And once we've done that, we can do https://github.com/rust-windowing/winit/pull/3386? Just proceed, waiting on reviews. Open an issue for feedback.

```rust
/// Small proposal how to address the custom cursor discussion.
impl EventLoop {
    fn create_cursor(...)
}

impl ActiveEventLoop {
    fn create_cursor(...)
}
```

Open pinned, locked issue for `v0.30` planning.
Previously: https://github.com/rust-windowing/winit/issues/2686

@madsmtm still needs to pick up #3386, and write a proper, really good changelog entry. Addressed above.

Continued from last time: Having discussions on `winit` vs. `winit-next`.
As long as Winit problems are discussed in Winit we are good.

Continued from last time: GitHub issues vs. discussions.
- Discussions are useful for user questions.
- Though maybe user questions should result in updated documentation instead?
  I think in general we have to address all opened issues with some kind of scrutiny of the documentation.
- Discussions are nicer for navigating since they contain threads, instead of single comments.
- People have to look in two places to find the information that they're looking for.

Conclusion:
- Create some issue templates.
- See if we can split up issues into smaller more actionable sub-issues and close issues that are not actionable.
- Leaving GitHub discussions, open until we come to a consensus.


## Allowing event subscribers

If we have time, maybe discuss proposal in https://github.com/rust-windowing/winit/issues/3432?

Nvmd, I didn't have time to write up the idea.

Building on idea from last meeting:

```rust
impl ApplicationHandler for EguiContext {
    // Maybe?
    fn event_is_handled(&self) -> bool {
        // ...
    }
    
    ...
}

impl ApplicationHandler for App {
    ...
}

let mut state = ...;

event_loop.run(|runner| { // A
    // 2, runner contains closure &mut dyn B
    // This closure is run on every event.

    // subscriber
    if runner.run(&mut state.egui_context) { // 3
        // event was consumed
        return
    }

    // user
    // 5
    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) {
    // 1
    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| { // B
        // 4
        // 6
        new_size = Some(app.resize(window_id));
    });
    // 7
}
```

Conclusion: Continue discussion in the issue. Whether this reaches v0.30 or not can be discussed there as well, once we have found a solution.


## Platform-specific event registration

https://github.com/rust-windowing/winit-next/issues/2
https://github.com/Smithay/smithay/pull/1169

Conclusion: Will need more work, one of us should do a more fleshed out proposal so it's easier to discuss how it'll work.

Idea A:
```rust
// Crate winit_macos
trait MacOSApplication: Application {
    fn open_files(&mut self, event_loop: ActiveEventLoop<'_>, files: &[&Path]);
}

struct VTable<A: Application> {
    open_files: Option<fn(&mut A, ActiveEventLoop<'_>, &[&Path])>,
}

impl EventLoopMacOS<A: Application> {
    fn wire_macos_handler(&self)
    where
        A: MacOSApplication
    {
        self.open_files = Some(T::open_files);
    }

    // Called by the system
    fn dispatch_do_thing(&mut self) {
        let Some(open_files) = self.vtable.open_files {
            open_files(self.state, self.event_loop, files);
        }
    }
}

// User crate
use winit_core::{Application, EventLoop, Window, WindowId, ...};
use winit_macos::{MacOSEventLoop, MacOSApplication};

struct App {
    window: Option<Window>,
}

impl Application for App {
    fn do_thing(&mut self, event_loop: ActiveEventLoop, window_id: WindowId) {
        let window = event_loop.get_window(&window_id);
        if let Some(window) = downcast_ref(window) {
            window.special_method();
        }
    }

    // Idea A1: IDET Pattern
    // fn macos(&mut self) -> Option<&mut dyn MacOSApplication> {
    //     Some(self)
    // }
}

impl MacOSApplication for App {
    fn open_files(&mut self, event_loop: ActiveEventLoop<'_>, files: &[&Path]) {
        dbg!(files);
    }
}

fn main() {
    let state = App;
    let event_loop: Box<dyn EventLoop> = EventLoop::create_new();

    // Idea A2:
    if let Some(event_loop) = downcast_ref<MacOSEventLoop>(&event_loop) {
        // Macos specific.
        event_loop.wire_macos_handler::<App>();
    }
    
    // winit_core.
    event_loop.run(state) // Application;
}
```

Idea B:
```rust
impl MacOSEventLoopExt for EventLoop {
    fn run_macos(self, app: impl Application + MacOSHandler);
}

fn main() {
    #[cfg(target_os = "macos")]
    event_loop.run_macos(app);

    #[cfg(target_os = "windows")]
    event_loop.run_windows(app);
}
```

Idea C:
???
