Skip to content

Conversation

@madsmtm
Copy link
Member

@madsmtm madsmtm commented Jan 25, 2024

As part of #3367, we're considering removing the generic on Event<T>, EventLoop<T>, EventLoopProxy<T> and the callback. By extension, we'd be getting rid of Event::UserEvent(T).

One approach to doing so would be to allow converting EventLoopProxy to the standard library's Waker type, which allows the user to wake a task (in this case the event loop) from any thread; then they can implement what they need themselves on top of that, using the standard library's mpsc::channel, mpsc::sync_channel or likewise, depending on their needs.

This is likely not a perfect solution for wakeups, we still need to properly figure out how to do timers; but this can get us some of the way there.

Blocked on #3449, we need to ensure that Sync is actually sound.

CC @notgull, I think this may be slightly useful for async?

Questions:

  • Do we need a UserWoken event, or is NewEvents is enough?
  • Should we hide the Waker behind a custom type like EventLoopWaker, in case we want to expose further functionality in the future?
    • We keep EventLoopProxy, and allow that to be converted to Waker.
  • Is Waker too heavy-weight for this? Can we just use a function wake(&self) on EventLoopProxy? Or maybe both?
  • Does the user need the ability to handle the case where the event loop has been destroyed? Or is that handled fine enough through other means, like in mpsc?

TODO:

  • Finish implementation on all platforms.
  • Properly test Waker implementations with updated example.
  • Add an entry to CHANGELOG.md.
  • Update documentation.

@madsmtm madsmtm added DS - appkit Affects the AppKit/macOS backend DS - win32 Affects the Win32/Windows backend DS - x11 Affects the X11 backend, or generally free Unix platforms DS - wayland Affects the Wayland backend, or generally free Unix platforms DS - android Affects the Android backend S - api Design and usability DS - uikit Affects the UIKit backend (iOS, tvOS, watchOS, visionOS) DS - web Affects the Web backend (WebAssembly/WASM) C - needs discussion Direction must be ironed out DS - orbital Affects the Orbital/Redox backend labels Jan 25, 2024
@madsmtm madsmtm force-pushed the waker branch 2 times, most recently from 87c7468 to 2c6aba9 Compare January 25, 2024 05:59
@kchibisov

This comment was marked as resolved.

@madsmtm madsmtm changed the title Add EventLoop::waker(&self) -> Waker Add EventLoopProxy::waker(self) -> Waker Jan 25, 2024
@madsmtm madsmtm force-pushed the waker branch 2 times, most recently from 78cd1d5 to 28f339f Compare January 25, 2024 14:46
Copy link
Contributor

@dhardy dhardy left a comment

Choose a reason for hiding this comment

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

I support this change: it makes winit simpler (at least at the API level).

Also, even though I currently use UserEvent, half the reason for that is just to create a Waker over it.

Comment on lines 494 to 500
// Note: This does not have the generic from `EventLoopProxy<T>`, since this
// is the new API that shouldn't need it.
impl From<EventLoopProxy> for Waker {
fn from(proxy: EventLoopProxy) -> Self {
proxy.waker()
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure this is wanted — eventually EventLoopProxy will (presumably) just be replaced with a Waker.

In fact, maybe just deprecate EventLoopProxy and create_proxy now, replacing with EventLoop::create_waker?

Copy link
Member

Choose a reason for hiding this comment

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

I want to reuse proxy in the future for some internal stuff in the future around Send/Sync and also, not be limited on the Waker API, since it's rather limited. But yeah, in the current state they are mostly the same.

@madsmtm madsmtm removed DS - appkit Affects the AppKit/macOS backend DS - win32 Affects the Win32/Windows backend DS - x11 Affects the X11 backend, or generally free Unix platforms DS - wayland Affects the Wayland backend, or generally free Unix platforms DS - android Affects the Android backend DS - uikit Affects the UIKit backend (iOS, tvOS, watchOS, visionOS) DS - web Affects the Web backend (WebAssembly/WASM) DS - orbital Affects the Orbital/Redox backend labels Jun 24, 2024
@nicoburns
Copy link
Contributor

We're doing this with custom code in Dioxus. It would definitely be nice to have in Winit.

@dhardy
Copy link
Contributor

dhardy commented Nov 10, 2025

  • Does the user need the ability to handle the case where the event loop has been destroyed?

No: the only purpose of waker is to awaken the event-loop. The current changes to winit (since v0.30) already force sending of user payloads through something like an mpsc channel, and this is fine in my opinion.

FYI I updated Kas to use winit last week in this PR: kas-gui/kas#583. You can also see my own Waker implementation there. So providing a waker in winit is not essential, but preferable considering how much unsafe code is required.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C - needs discussion Direction must be ironed out S - api Design and usability

Development

Successfully merging this pull request may close these issues.

6 participants