-
Notifications
You must be signed in to change notification settings - Fork 921
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Winit run_return
and Android does not get Resumed
and Suspended
#2706
Comments
run_return
and Androidrun_return
and Android does not get Resumed
and Suspended
Curious - at least from an initial inspection it wasn't obvious to me why that wouldn't work. My initial thought was that I'd be cautious about moving the handling code for any specific Winit events (such as Technically this is currently only needed for the Looking at tracing what happens with your example then what I see is that the Java thread is being blocked very early on when setting the app state to I think the issue comes from how Winit has a special case for the first iteration of the mainloop with a I don't think In this respect the Android backend currently copies what is also done in the Windows and Linux backends. (I couldn't see on a quick inspection how the MacOS backend handles For this example I think this special case iteration of the mainloop at the start of As an experiment I made this hacky change to the Android backend and got the example working: diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs
index 68e4cf66..563a1c31 100644
--- a/src/platform_impl/android/mod.rs
+++ b/src/platform_impl/android/mod.rs
@@ -694,6 +694,7 @@ impl<T: 'static> EventLoop<T> {
let mut pending_redraw = false;
// run the initial loop iteration
+ /*
let mut iter_result = self.single_iteration(
&mut control_flow,
None,
@@ -701,9 +702,12 @@ impl<T: 'static> EventLoop<T> {
&mut cause,
&mut callback,
);
+ */
+ let mut iter_result = IterationResult { deadline: None, timeout: None, wait_start: Instant::now() };
let exit_code = loop {
if let ControlFlow::ExitWithCode(code) = control_flow {
+ log::debug!("run_return: early exit with code");
break code;
}
I guess it should be possible to handle this more neatly with some extra care around when the Currently I think some other backends work in a similar way to the Android backend and I'm not sure atm but maybe it's useful for other use cases that the |
For reference, here's a related issue on macos, for a different use case: #2431 |
It could be good to understand the use case a bit more here. Can you maybe say why you're trying to move some event loop handling outside of the winit callback? I have a feeling that the reason for wanting this pattern might instead imply a different shortcoming with Winit that can potentially be addressed, so that you can keep your event loop handing inside Winit's event loop. Needing to support using Maybe a different event polling API could be made available on platforms where that is possible though, for situations like this where you're effectively embedding Winit into an external event loop. |
that's not related issue though. The mentioned issue was asking "how to create event loop ondemand to perform window requests". |
Yeah, I figured it was related enough to mention here, since it represented a different use case for I'm not suggesting it's a duplicate, just potentially related enough for added context here. It's an example of wanting to call |
Thanks @rib for looking into to this issue! I wasn't aware that calling Regarding the use-case of why to use The documentation about
But does not expand on why not to use it or what it's purpose is. Either way I'm looking for some kind of solution to work around this limitation, one alternative could be to switch to |
Yeah the docs aren't particularly clear about it's behaviour.
In addition to running a
I can sort of see the appeal in not having to bend to how Winit defines its event loop but at the same time I think Winit's design generally comes from trying to provide an abstraction that can work across OSs/window systems and some window systems aren't compatible with that kind of Take for example web. On web the "loop" is an illusion because its fundamentally not possible to create a long running loop that would block the browser. In this case the loop is really just an abstraction over the browser's internal event loop and it's not possible to explicitly poll for events in a browser, like you can on Linux / Android. Its been a while since I've looked a macos / ios closely but I think it could be tricky to support that model there too. Although they use If you only need to be portable across Android, Linux and Windows then I think it might be possible to integrate Winit into an external event loop, similar to the example above - but yeah, it would at least require a change similar to above.
Incidentally when I first started having a look at this the other day, I realized that the Android backend's implementation of Did you maybe hit some specific road block from being able drive your own event / rendering / frame processing from within Winit? It should ideally be possible to drive the same logic that you'd have in the outer loop, between At it's core, Winit is designed to provide a portable event loop for graphical apps, so if you're looking at side stepping that event loop that's not really a good sign :) The event loop is the crux of what Winit is. If there's some technical limitation that means Winit isn't able to run your apps main loop then it would be good to understand that and hopefully address that. I probably wouldn't worry too much about callstack depth - the backend abstractions for running the event loop in Winit are pretty shallow as far as I've seen. Winit does add complexity though for sure. There is some inherent complexity with abstracting across window systems though and it might be hard to avoid unless you know you only care about a limited set of platforms. |
In an attempt to keep the discussions more focused there seems be two main topics.
Topic 1, run_return not workingWith regards topic 1, I'm wondering if the hacky fix you suggested has a more mature variant? Seeing how the current issue is preventing the use of Topic 2, why use run_returnRegarding the second topic, why does There are as you point out @rib hard to make a single interface for such a large variety of different ways of handling message loops and preferences. So I see it as a great strength that And as last thing I want to highlight the usage of winit for me is developing a game. So maybe that in it self skews the perception of how the flow should work. |
Topic 1, run_return not workingI guess this is up in the air atm, because we aren't clear about what working means currently. If we just think of The implementation of pub fn run<F>(mut self, event_handler: F) -> !
where
F: 'static + FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow),
{
let exit_code = self.run_return(event_handler);
::std::process::exit(exit_code);
} iOS and web are the two exceptions that don't provide a Topic 2, why use run_returnAlthough I wasn't around when also see: https://gist.github.com/Osspial/53efa87797899872650f6bece14736c0 for the original design proposal that gives some good background here. Historically there were two APIs So historically it looks like Interestingly Windows was a key motivator at the time for switching over to the current callback design due to how Windows creates a nested loop when handling window resizing. (I had thought Windows was one of the OSs where you could actually get away with polling) It looks like the older design was also very problematic for macos too: #231 (comment) I think your hunch is probably right when you say:
The documentation does still give hints that it was originally intended to be used for polling events but it can't really be used like that any more since that's not really a model that can be supported consistently across OSs (in addition to the specific issue caused by the At this point Current conclusionConsidering that Winit has already explored being based on a polling model in the past, and that didn't work out I think we probably shouldn't be pushing to re-introduce support for event polling via E.g. on Android that model can't work for events where the handling needs to be synchronized with the Java thread (such as ProposalI think I'd currently advocate for removing This was also what we started to discuss recently here: #2709 Unfortunately (since I see you aren't keen on not owning the loop itself) this would mean that you'd have to move your event handling inside the Winit event loop, but I think, practically, this is the only portable solution really. Did you maybe hit other technical issues from already trying to drive your game engine logic from within the Winit event loop that need to be considered here? (apart from not being keen on the layering / lack of ownership) Game engine requirementsI don't think I'd generally expect the callback model of Winit to be a problem for a game engine (e.g. this is inherently how it works on MacOS, iOS and Web) but I can think of things about Winit that are lacking that will be important for a game engine or UI toolkit (e.g. no good story yet for scheduling and throttling rendering). Winit also doesn't give many ways to punch holes and do platform-specific things in situations where you want to be pragmatic and handle something directly while there isn't yet a platform-agnostic abstraction provided by Winit. Hopefully these kinds of shortcomings can be addressed incrementally within Winit though and testing out solutions with the context of a specific game engine / use case should be able to help with that too if there are specific blocking problems being hit with the current design. RFCMaybe @kchibisov, @madsmtm and @msiglreith are more familiar with the historic usage of |
Not familiar with the history of Linking the lightning talk that |
Because desktop clients don't want to terminate for example, they might want to do some cleanups, ect. For example alacritty is using
Yes, the winit design is driven by platforms like that, because they can't do much because how tie they are to the windowing system. On X11/Wayland it's not an issue for example.
It doesn't terminate the entire app, that's the point why it exits and used. How you're going to use(like normal
As long as it doesn't terminate the entire program I'm fine with it. Be aware that if you consider that it'll never return, but we won't tell you is a solution, it's not, I swear it'll break the destructors or user cleanup logic, so the current spilt is necessary. If
polling based on
Winit can provide such stuff on the application level only, e.g. wayland frame callbacks, request animation frame and so on. Game engines should simply use the underlying OpenGL api's for such stuff and simply run a timer, they could build a timer on top of winit if they don't want high precision, because for example Windows sucks a timers. An example of timer and frame scheduling along the winit is done in alacritty. We use both frame callbacks, timer based rendering (to not use Vsync because it's bugged), and drive all
You might want to look into the |
Re |
I guess we can now. Though, we don't really want to, unless |
yeah, I can see the trade off here but overall I tend to think that it's even worse that Calling In some situations there can be meaningful code that goes after the If the code after the It seems like these caveats could be explained quite easily in the docs for |
I mean the destructors are being executed from inside. I wonder how you close on Though, I have no clue about such platforms, but I have a feeling that they let you know that you're returning and execting, you just not allowed to run anything again or something like that, which should be fine. |
This is the key question here really; do you think It looks like This isn't just an issue with Android - the same polling approach also would not work on Linux or Windows as far as I can tell, with the current way Event polling is also fundamentally incompatible with MacOS, iOS and Web so it would seem surprising that you'd want to support that usage model for If we want to try and support event polling via
|
This also relates to the question of whether |
Just so you know, event pooling with run return is used in the wild and works. One such project is https://github.com/smithay/smithay. They can't run their stuff inside winit, so they need a way to poll ondemand.
yeah, the way it communicates the events right now is unfortunate.
It's explained https://docs.rs/winit/0.28.2/winit/platform/run_return/trait.EventLoopExtRunReturn.html#caveats In fact the original docs were written in a way that you poll via the |
I guess Smithay only supports Linux in this context though so it's maybe a bit of a special case that it can rely on the behaviour of the one platform that is most compatible with a polling based model. I could imagine that if More generally for supporting cross-platform frameworks it doesn't look like polling can be supported in a portable way though. |
Looking a little bit closer at the Linux implementation of I'm not quite clear what the behaviour is for other backends is atm. I would expect that any wake up cause would be associated with a full iteration of the loop, including |
The question in this thread boils down to poll based vs event-based approach. There is likely not a one-fit-all answer on which system is better for all platforms and scenarios. And it also depends on the project motivation of winit. This is where I like @rib case "a different event polling API could be made available on platforms where that is possible". For a game engine, it is essential to have control over update rates. And it is preferable to not depend on an external opensource library to control the main loop for us even being it by using In my view, I would like to see winit to be a black box that provides events when I poll for it. Just like mio does or I did in crossterm. As a developer, I like control over my application without a black box taking care of the execution of it.
A poll-based API is very flexible and a closure system could be built on top of it. It is proven to work when interfacing with system io like with mio. You kinda invert the flow direction which is counter-intuitive for rust but if done well it opens up different designs and could remain to support the closure approach. Perhaps winit should consider removing the |
Yeah, that's a bit unfortunate.
That's impossible though, since some events are The main issue with the polling API is that it doesn't really work anywhere except X11/Wayland. Though, for game engine I doubt you care about the resizes at all. You can't also block polling for the events like you can on let's say, Linux on macOS.
We could probably modal polling API with the caveat that it's broken on Windows/macOS because they want SYNC behavior and that GUI toolkits shouldn't use it. For games you likely don't care about such things. |
We do process resize and need to rebind our window to the backend, save new window dimensions, update egui DPI, and some other things on resize. I am not sure if I follow why a polling system breaks synchronous order in events? |
@TimonPost once macOS sends you a resize and asks to I mean for game it doesn't matter, because you don't care about how smooth your resizes are in the end, but for UI gui clients it does matter. You can test yourself by resizing alacritty on macOS and see how viewport glitches because we do |
Yeah, I pushed for this because there was a separate difficulty before with being able to write portable code that could initialize render state in a way that was properly synchronized with Android's lifecycle. Tbh though I didn't appreciate that applications were trying to use I think there are currently quite a few oddities / inconsistencies atm with what events get dispatched if
If Winit wants to really try and support polling it would be good to re-evaluate those kinds of events that are more related to a full app/event loop lifecycle. |
I think we could maybe expose a Also, |
I can see some of the appeal but still tend to think that pushing for a polling model is not the ideal solution (though it could be a short-term pragmatic solution for a game engine that's currently based on that model). I don't really see it as the lower common denominator as described because some window systems are callback based and non-pollable. The polling model mainly just works nicely on Linux since it's the only OS that is very consistent with driving all window system events via file descriptors that can be efficiently polled. For all other OSs (including Android that's based on Linux) there is some amount of impedance mismatch with this model - up to the point of being incompatible with iOS and Web. I like the idea of an MIO based event loop (I recently started a side experiment to look at implementing just this) but in the context of something like Winit it's not going to be as simple as just polling via a standalone MIO selector as the one source of events because on some platforms we're forced to integrate with a loop that's provided by the system. On Android we have to integrate with a In the case of RunLoop integration on MacOS / iOS there's no underlying, low-level kqueue file descriptor for the loop like you'd have on Linux, and so you have to rely on the RunLoop implementation (as a black box) to handle efficiently waiting when there are no events. It would be possible for us to attach our own kqueue file descriptor for additional events to a RunLoop but not the reverse. The upshot here is that there is no efficient way of polling for events. On MacOS (not iOS) you can repeatedly "stop" the app to exit the RunLoop and then re-run it to approximate polling but it's still not really the same as being able to poll a file descriptor. E.g. I guess you'd have to hack in a special RunLoop source to try and emulate a timeout of zero and I'd expect this would use a disproportionate amount of CPU compared to polling a file descriptor. Overall there are specific issues with polling across Windows, Android, MacOS, iOS and Web that all tend to suggest that the callback approach is the more portable model for any kind of cross-platform graphical application, including for a game engine. This wouldn't necessarily preclude having some fairly monolithic callbacks for driving complex game engine updates. Without looking at the specifics it's hard to really help evaluate what the technical / practical challenges are with moving code that currently resides in an app-owned loop inside a Winit closure but maybe if there are some specific reasons why that's tricky currently then it might separately be possible to make changes to Winit that would make that easier, so it's easier to adopt a more portable callback model. E.g. I wonder if one thing that could help would be some accurate timer APIs to help schedule work in sync with rendering deadlines. E.g. one common strategy for minimizing latency in a game engine is to try and delay updates and rendering as late as possible before your presentation deadline. Right now there's no clear way to do that via a callback in Winit and I could imagine finding the polling model more convenient, basically as a workaround for other features that are missing from Winit. Some of the portability hazards with the polling model...WindowsI'm not very familiar with this one but my rough understanding is that polling can become blocked indefinitely during resizing due to how a nested, modal event loop gets run to handle the resize events. (not sure atm if this is an architectural issue with Winit or if it's a fundamental issue with how Windows is designed) AndroidAny event, such as a lifecycle event, that originates from the Java thread will involve synchronization between the Java thread and the native main() thread (i.e. that Java callback is blocked from returning until the native code has handled the event). For some of those event the Java callback that is delivering that event will assume that the event has been handled before it returns. Examples of this include notifications of the window/surface being destroyed or a request to MacOS / iOSThe main one I'm aware of is that UIView draw events are supposed to be handled inline within the callback from the OS and can't be deferred. MacOS / iOS is all delegate / callback based though and I would tend to assume there are numerous callbacks where the system expects the event to be handled in the callback itself. Generally speaking lifecycle events should almost certainly be handled with their callback because it just doesn't conceptually make sense to buffer a lifecycle event and handle after the next poll, because the lifecycle state might then be out of date. For instance if you're being moved into the background or get some clue that your about to be closed then you may need to save state asap otherwise it might be too late if you buffer and handle via polling. iOS can't be polled because WebWeb-based event loop support is basically all callback based because the event loop is managed within the browser. An application can't run it's own loop with polling since that would block the browser. SummaryIt might be possible to find tricky workarounds for some of these to stick with a polling model on some platforms but I think the model is mainly just compatible with Linux and Windows. It looks like it could become more complex over time to be sticking with a polling model on MacOS and Android and impossible on iOS and Web. What should we do here?Personally I think at this point that the current I'd still advocate for removing For the polling use case we could add a separate set of event loop APIs like
It's not obvious how to define when With these APIs then I'd still be a bit concerned that it's confusing / misleading for a cross-platform window system API to be supporting a completely distinct event loop model that isn't portable, but at the same time I do sympathize with wanting to support an existing code based that's currently based around a polling model and doesn't support the full set of platforms that Winit does. |
Overall this re-works the APIs for how an `EventLoop` is run to cover these use-cases, with varying portability caveats: 1. A portable `run()` API that consumes the `EventLoop` and runs the loop on the calling thread until the app exits. This can be supported across _all_ platforms and compared to the previous `run() -> !` API is now able to return a `Result` status on all platforms except iOS and Web. Fixes: rust-windowing#2709 2. A less portable `run_ondmand()` API that covers the use case in rust-windowing#2431 where applications need to be able to re-run a Winit application multiple times against a persistent `EventLoop`. This doesn't allow `Window` state to carry across separate runs of the loop, but does allow orthogonal re-instantiations of a gui application. Available On: Windows, Linux, MacOS Could be supported on Android if there's a use case Incompatible with iOS, Web Fixes: rust-windowing#2431 3. A less portable (and on MacOS, likely less-optimal) `pump_events()` API that covers the use case in rust-windowing#2706 and allows a Winit event loop to be embedded within an external `loop {}`. Applications call `pump_events()` once per iteration of their own external loop to dispatch all pending Winit events, without blocking the external loop. Available On: Windows, Linux, MacOS, Android Incompatible With: iOS, Web Fixes: rust-windowing#2706 Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) In particular by moving away from `run() -> !` we stop calling `std::process::exit()` internally as a means to kill the process without returning which means it's possible to return an exit status and applications can return from their `main()` function normally. This also fixes Android support where an Activity runs in a thread but we can't assume to have full ownership of the process (other services could be running in separate threads). `run_return` has been removed, and the overlapping use cases that `run_return` previously partially aimed to support have been split across `run_ondemand` and `pump_events`. To help test the changes this adds: examples/window_ondemand examples/window_pump_events examples/window_pump_events_rfd The last _rfd example, tests the interaction between the `rfd` crate and using `pump_events` to embed Winit within an external event loop. Additionally all examples have generally been updated so that `main()` returns a `Result` from `run()` Fixes: rust-windowing#2709 Fixes: rust-windowing#2706 Fixes: rust-windowing#2431 Fixes: rust-windowing#2752 TODO: Linux TODO: split patch up
Overall this re-works the APIs for how an `EventLoop` is run to cover these use-cases, with varying portability caveats: 1. A portable `run()` API that consumes the `EventLoop` and runs the loop on the calling thread until the app exits. This can be supported across _all_ platforms and compared to the previous `run() -> !` API is now able to return a `Result` status on all platforms except iOS and Web. Fixes: rust-windowing#2709 2. A less portable `run_ondmand()` API that covers the use case in rust-windowing#2431 where applications need to be able to re-run a Winit application multiple times against a persistent `EventLoop`. This doesn't allow `Window` state to carry across separate runs of the loop, but does allow orthogonal re-instantiations of a gui application. Available On: Windows, Linux, MacOS Could be supported on Android if there's a use case Incompatible with iOS, Web Fixes: rust-windowing#2431 3. A less portable (and on MacOS, likely less-optimal) `pump_events()` API that covers the use case in rust-windowing#2706 and allows a Winit event loop to be embedded within an external `loop {}`. Applications call `pump_events()` once per iteration of their own external loop to dispatch all pending Winit events, without blocking the external loop. Available On: Windows, Linux, MacOS, Android Incompatible With: iOS, Web Fixes: rust-windowing#2706 Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) In particular by moving away from `run() -> !` we stop calling `std::process::exit()` internally as a means to kill the process without returning which means it's possible to return an exit status and applications can return from their `main()` function normally. This also fixes Android support where an Activity runs in a thread but we can't assume to have full ownership of the process (other services could be running in separate threads). `run_return` has been removed, and the overlapping use cases that `run_return` previously partially aimed to support have been split across `run_ondemand` and `pump_events`. To help test the changes this adds: examples/window_ondemand examples/window_pump_events examples/window_pump_events_rfd The last _rfd example, tests the interaction between the `rfd` crate and using `pump_events` to embed Winit within an external event loop. Additionally all examples have generally been updated so that `main()` returns a `Result` from `run()` Fixes: rust-windowing#2709 Fixes: rust-windowing#2706 Fixes: rust-windowing#2431 Fixes: rust-windowing#2752 TODO: tidy up macos changes - probably lots of debug stuff left in atm TODO: Linux TODO: ask someone to test orbital changes, made blindly TODO: split patch up
Overall this re-works the APIs for how an `EventLoop` is run to cover these use-cases, with varying portability caveats: 1. A portable `run()` API that consumes the `EventLoop` and runs the loop on the calling thread until the app exits. This can be supported across _all_ platforms and compared to the previous `run() -> !` API is now able to return a `Result` status on all platforms except iOS and Web. Fixes: rust-windowing#2709 2. A less portable `run_ondmand()` API that covers the use case in rust-windowing#2431 where applications need to be able to re-run a Winit application multiple times against a persistent `EventLoop`. This doesn't allow `Window` state to carry across separate runs of the loop, but does allow orthogonal re-instantiations of a gui application. Available On: Windows, Linux, MacOS Could be supported on Android if there's a use case Incompatible with iOS, Web Fixes: rust-windowing#2431 3. A less portable (and on MacOS, likely less-optimal) `pump_events()` API that covers the use case in rust-windowing#2706 and allows a Winit event loop to be embedded within an external `loop {}`. Applications call `pump_events()` once per iteration of their own external loop to dispatch all pending Winit events, without blocking the external loop. Available On: Windows, Linux, MacOS, Android Incompatible With: iOS, Web Fixes: rust-windowing#2706 Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) In particular by moving away from `run() -> !` we stop calling `std::process::exit()` internally as a means to kill the process without returning which means it's possible to return an exit status and applications can return from their `main()` function normally. This also fixes Android support where an Activity runs in a thread but we can't assume to have full ownership of the process (other services could be running in separate threads). `run_return` has been removed, and the overlapping use cases that `run_return` previously partially aimed to support have been split across `run_ondemand` and `pump_events`. To help test the changes this adds: examples/window_ondemand examples/window_pump_events examples/window_pump_events_rfd The last _rfd example, tests the interaction between the `rfd` crate and using `pump_events` to embed Winit within an external event loop. Additionally all examples have generally been updated so that `main()` returns a `Result` from `run()` Fixes: rust-windowing#2709 Fixes: rust-windowing#2706 Fixes: rust-windowing#2431 Fixes: rust-windowing#2752 TODO: X11/Wayland backends TODO: ask someone to test orbital changes, made blindly TODO: split patch up Second pass over the windows backend I had totally underestimated what was involved in updating the windows backend since I hadn't seen the special `wait_thread` that was also dispatching messages and implementing control_flow timeouts via MsgWaitForMultipleObjects, nor had I grokked all the special stuff being done with `WM_PAINT` messages. This "breaks" the MainEventsCleared -> RedrawRequested -> RedrawEventsCleared ordering guarantees, similar to how this is anyway inherently broken in the MacOS backend. The switches to using SetTimer to handle control_flow Wait timeouts and removes the need to use MsgWaitForMultipleObjects. Overall this is a pretty nice simplification of several things TODO: tidy up (lots of debug and misc changes + comments atm) stash
Overall this re-works the APIs for how an `EventLoop` is run to cover these use-cases, with varying portability caveats: 1. A portable `run()` API that consumes the `EventLoop` and runs the loop on the calling thread until the app exits. This can be supported across _all_ platforms and compared to the previous `run() -> !` API is now able to return a `Result` status on all platforms except iOS and Web. Fixes: rust-windowing#2709 2. A less portable `run_ondmand()` API that covers the use case in rust-windowing#2431 where applications need to be able to re-run a Winit application multiple times against a persistent `EventLoop`. This doesn't allow `Window` state to carry across separate runs of the loop, but does allow orthogonal re-instantiations of a gui application. Available On: Windows, Linux, MacOS Could be supported on Android if there's a use case Incompatible with iOS, Web Fixes: rust-windowing#2431 3. A less portable (and on MacOS, likely less-optimal) `pump_events()` API that covers the use case in rust-windowing#2706 and allows a Winit event loop to be embedded within an external `loop {}`. Applications call `pump_events()` once per iteration of their own external loop to dispatch all pending Winit events, without blocking the external loop. Available On: Windows, Linux, MacOS, Android Incompatible With: iOS, Web Fixes: rust-windowing#2706 Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) In particular by moving away from `run() -> !` we stop calling `std::process::exit()` internally as a means to kill the process without returning which means it's possible to return an exit status and applications can return from their `main()` function normally. This also fixes Android support where an Activity runs in a thread but we can't assume to have full ownership of the process (other services could be running in separate threads). `run_return` has been removed, and the overlapping use cases that `run_return` previously partially aimed to support have been split across `run_ondemand` and `pump_events`. To help test the changes this adds: examples/window_ondemand examples/window_pump_events examples/window_pump_events_rfd The last _rfd example, tests the interaction between the `rfd` crate and using `pump_events` to embed Winit within an external event loop. Additionally all examples have generally been updated so that `main()` returns a `Result` from `run()` Fixes: rust-windowing#2709 Fixes: rust-windowing#2706 Fixes: rust-windowing#2431 Fixes: rust-windowing#2752 TODO: X11/Wayland backends TODO: ask someone to test orbital changes, made blindly TODO: split patch up Second pass over the windows backend I had totally underestimated what was involved in updating the windows backend since I hadn't seen the special `wait_thread` that was also dispatching messages and implementing control_flow timeouts via MsgWaitForMultipleObjects, nor had I grokked all the special stuff being done with `WM_PAINT` messages. This "breaks" the MainEventsCleared -> RedrawRequested -> RedrawEventsCleared ordering guarantees, similar to how this is anyway inherently broken in the MacOS backend. The switches to using SetTimer to handle control_flow Wait timeouts and removes the need to use MsgWaitForMultipleObjects. Overall this is a pretty nice simplification of several things TODO: tidy up (lots of debug and misc changes + comments atm) stash
Overall this re-works the APIs for how an `EventLoop` is run to cover these use-cases, with varying portability caveats: 1. A portable `run()` API that consumes the `EventLoop` and runs the loop on the calling thread until the app exits. This can be supported across _all_ platforms and compared to the previous `run() -> !` API is now able to return a `Result` status on all platforms except iOS and Web. Fixes: rust-windowing#2709 2. A less portable `run_ondmand()` API that covers the use case in rust-windowing#2431 where applications need to be able to re-run a Winit application multiple times against a persistent `EventLoop`. This doesn't allow `Window` state to carry across separate runs of the loop, but does allow orthogonal re-instantiations of a gui application. Available On: Windows, Linux, MacOS Could be supported on Android if there's a use case Incompatible with iOS, Web Fixes: rust-windowing#2431 3. A less portable (and on MacOS, likely less-optimal) `pump_events()` API that covers the use case in rust-windowing#2706 and allows a Winit event loop to be embedded within an external `loop {}`. Applications call `pump_events()` once per iteration of their own external loop to dispatch all pending Winit events, without blocking the external loop. Available On: Windows, Linux, MacOS, Android Incompatible With: iOS, Web Fixes: rust-windowing#2706 Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) In particular by moving away from `run() -> !` we stop calling `std::process::exit()` internally as a means to kill the process without returning which means it's possible to return an exit status and applications can return from their `main()` function normally. This also fixes Android support where an Activity runs in a thread but we can't assume to have full ownership of the process (other services could be running in separate threads). `run_return` has been removed, and the overlapping use cases that `run_return` previously partially aimed to support have been split across `run_ondemand` and `pump_events`. To help test the changes this adds: examples/window_ondemand examples/window_pump_events examples/window_pump_events_rfd The last _rfd example, tests the interaction between the `rfd` crate and using `pump_events` to embed Winit within an external event loop. Additionally all examples have generally been updated so that `main()` returns a `Result` from `run()` Fixes: rust-windowing#2709 Fixes: rust-windowing#2706 Fixes: rust-windowing#2431 Fixes: rust-windowing#2752 TODO: X11/Wayland backends TODO: ask someone to test orbital changes, made blindly TODO: split patch up Second pass over the windows backend I had totally underestimated what was involved in updating the windows backend since I hadn't seen the special `wait_thread` that was also dispatching messages and implementing control_flow timeouts via MsgWaitForMultipleObjects, nor had I grokked all the special stuff being done with `WM_PAINT` messages. This "breaks" the MainEventsCleared -> RedrawRequested -> RedrawEventsCleared ordering guarantees, similar to how this is anyway inherently broken in the MacOS backend. The switches to using SetTimer to handle control_flow Wait timeouts and removes the need to use MsgWaitForMultipleObjects. Overall this is a pretty nice simplification of several things TODO: tidy up (lots of debug and misc changes + comments atm) stash
Overall this re-works the APIs for how an `EventLoop` is run to cover these use-cases, with varying portability caveats: 1. A portable `run()` API that consumes the `EventLoop` and runs the loop on the calling thread until the app exits. This can be supported across _all_ platforms and compared to the previous `run() -> !` API is now able to return a `Result` status on all platforms except iOS and Web. Fixes: rust-windowing#2709 2. A less portable `run_ondmand()` API that covers the use case in rust-windowing#2431 where applications need to be able to re-run a Winit application multiple times against a persistent `EventLoop`. This doesn't allow `Window` state to carry across separate runs of the loop, but does allow orthogonal re-instantiations of a gui application. Available On: Windows, Linux, MacOS Could be supported on Android if there's a use case Incompatible with iOS, Web Fixes: rust-windowing#2431 3. A less portable (and on MacOS, likely less-optimal) `pump_events()` API that covers the use case in rust-windowing#2706 and allows a Winit event loop to be embedded within an external `loop {}`. Applications call `pump_events()` once per iteration of their own external loop to dispatch all pending Winit events, without blocking the external loop. Available On: Windows, Linux, MacOS, Android Incompatible With: iOS, Web Fixes: rust-windowing#2706 Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) In particular by moving away from `run() -> !` we stop calling `std::process::exit()` internally as a means to kill the process without returning which means it's possible to return an exit status and applications can return from their `main()` function normally. This also fixes Android support where an Activity runs in a thread but we can't assume to have full ownership of the process (other services could be running in separate threads). `run_return` has been removed, and the overlapping use cases that `run_return` previously partially aimed to support have been split across `run_ondemand` and `pump_events`. To help test the changes this adds: examples/window_ondemand examples/window_pump_events examples/window_pump_events_rfd The last _rfd example, tests the interaction between the `rfd` crate and using `pump_events` to embed Winit within an external event loop. Additionally all examples have generally been updated so that `main()` returns a `Result` from `run()` Fixes: rust-windowing#2709 Fixes: rust-windowing#2706 Fixes: rust-windowing#2431 Fixes: rust-windowing#2752 TODO: X11/Wayland backends TODO: ask someone to test orbital changes, made blindly TODO: split patch up
Overall this re-works the APIs for how an `EventLoop` is run to cover these use-cases, with varying portability caveats: 1. A portable `run()` API that consumes the `EventLoop` and runs the loop on the calling thread until the app exits. This can be supported across _all_ platforms and compared to the previous `run() -> !` API is now able to return a `Result` status on all platforms except iOS and Web. Fixes: rust-windowing#2709 2. A less portable `run_ondmand()` API that covers the use case in rust-windowing#2431 where applications need to be able to re-run a Winit application multiple times against a persistent `EventLoop`. This doesn't allow `Window` state to carry across separate runs of the loop, but does allow orthogonal re-instantiations of a gui application. Available On: Windows, Linux, MacOS Could be supported on Android if there's a use case Incompatible with iOS, Web Fixes: rust-windowing#2431 3. A less portable (and on MacOS, likely less-optimal) `pump_events()` API that covers the use case in rust-windowing#2706 and allows a Winit event loop to be embedded within an external `loop {}`. Applications call `pump_events()` once per iteration of their own external loop to dispatch all pending Winit events, without blocking the external loop. Available On: Windows, Linux, MacOS, Android Incompatible With: iOS, Web Fixes: rust-windowing#2706 Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) In particular by moving away from `run() -> !` we stop calling `std::process::exit()` internally as a means to kill the process without returning which means it's possible to return an exit status and applications can return from their `main()` function normally. This also fixes Android support where an Activity runs in a thread but we can't assume to have full ownership of the process (other services could be running in separate threads). `run_return` has been removed, and the overlapping use cases that `run_return` previously partially aimed to support have been split across `run_ondemand` and `pump_events`. To help test the changes this adds: examples/window_ondemand examples/window_pump_events examples/window_pump_events_rfd The last _rfd example, tests the interaction between the `rfd` crate and using `pump_events` to embed Winit within an external event loop. Additionally all examples have generally been updated so that `main()` returns a `Result` from `run()` Fixes: rust-windowing#2709 Fixes: rust-windowing#2706 Fixes: rust-windowing#2431 Fixes: rust-windowing#2752 TODO: X11/Wayland backends TODO: ask someone to test orbital changes, made blindly TODO: split patch up
Overall this re-works the APIs for how an `EventLoop` is run to cover these use-cases, with varying portability caveats: 1. A portable `run()` API that consumes the `EventLoop` and runs the loop on the calling thread until the app exits. This can be supported across _all_ platforms and compared to the previous `run() -> !` API is now able to return a `Result` status on all platforms except iOS and Web. Fixes: rust-windowing#2709 2. A less portable `run_ondmand()` API that covers the use case in rust-windowing#2431 where applications need to be able to re-run a Winit application multiple times against a persistent `EventLoop`. This doesn't allow `Window` state to carry across separate runs of the loop, but does allow orthogonal re-instantiations of a gui application. Available On: Windows, Linux, MacOS Could be supported on Android if there's a use case Incompatible with iOS, Web Fixes: rust-windowing#2431 3. A less portable (and on MacOS, likely less-optimal) `pump_events()` API that covers the use case in rust-windowing#2706 and allows a Winit event loop to be embedded within an external `loop {}`. Applications call `pump_events()` once per iteration of their own external loop to dispatch all pending Winit events, without blocking the external loop. Available On: Windows, Linux, MacOS, Android Incompatible With: iOS, Web Fixes: rust-windowing#2706 Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) In particular by moving away from `run() -> !` we stop calling `std::process::exit()` internally as a means to kill the process without returning which means it's possible to return an exit status and applications can return from their `main()` function normally. This also fixes Android support where an Activity runs in a thread but we can't assume to have full ownership of the process (other services could be running in separate threads). `run_return` has been removed, and the overlapping use cases that `run_return` previously partially aimed to support have been split across `run_ondemand` and `pump_events`. To help test the changes this adds: examples/window_ondemand examples/window_pump_events examples/window_pump_events_rfd The last _rfd example, tests the interaction between the `rfd` crate and using `pump_events` to embed Winit within an external event loop. Additionally all examples have generally been updated so that `main()` returns a `Result` from `run()` Fixes: rust-windowing#2709 Fixes: rust-windowing#2706 Fixes: rust-windowing#2431 Fixes: rust-windowing#2752 TODO: X11/Wayland backends TODO: ask someone to test orbital changes, made blindly TODO: split patch up
This adds two new extensions for running a Winit event loop which will replace `EventLoopExtRunReturn` The `run_return` API is trying to solve multiple problems and address multiple, unrelated, use cases but in doing so it is not succeeding at addressing any of them fully. The notable use cases we have are: 1. Applications want to be able to implement their own external event loop and call some Winit API to poll / pump events, once per iteration of their own loop, without blocking the outer, external loop. Addressing rust-windowing#2706 2. Applications want to be able to re-run separate instantiations of some Winit-based GUI and want to allow the event loop to exit with a status, and then later be able to run the loop again for a new instantiation of their GUI. Addressing rust-windowing#2431 It's very notable that these use cases can't be supported across all platforms and so they are extensions, similar to `EventLoopExtRunReturn` The intention is to support these extensions on: - Windows - Linux (X11 + Wayland) - macOS - Android These extensions aren't compatible with Web or iOS though. Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) Once all backends have support for these extensions then we can remove `EventLoopExtRunReturn` For simplicitly, the extensions are documented with the assumption that the above platforms will be supported. This patch makes no functional change, it only introduces these new extensions so we can then handle adding platform-specific backends in separate pull requests, so the work can be landed in stages.
This adds two new extensions for running a Winit event loop which will replace `EventLoopExtRunReturn` The `run_return` API is trying to solve multiple problems and address multiple, unrelated, use cases but in doing so it is not succeeding at addressing any of them fully. The notable use cases we have are: 1. Applications want to be able to implement their own external event loop and call some Winit API to poll / pump events, once per iteration of their own loop, without blocking the outer, external loop. Addressing rust-windowing#2706 2. Applications want to be able to re-run separate instantiations of some Winit-based GUI and want to allow the event loop to exit with a status, and then later be able to run the loop again for a new instantiation of their GUI. Addressing rust-windowing#2431 It's very notable that these use cases can't be supported across all platforms and so they are extensions, similar to `EventLoopExtRunReturn` The intention is to support these extensions on: - Windows - Linux (X11 + Wayland) - macOS - Android These extensions aren't compatible with Web or iOS though. Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) Once all backends have support for these extensions then we can remove `EventLoopExtRunReturn` For simplicitly, the extensions are documented with the assumption that the above platforms will be supported. This patch makes no functional change, it only introduces these new extensions so we can then handle adding platform-specific backends in separate pull requests, so the work can be landed in stages.
This adds two new extensions for running a Winit event loop which will replace `EventLoopExtRunReturn` The `run_return` API is trying to solve multiple problems and address multiple, unrelated, use cases but in doing so it is not succeeding at addressing any of them fully. The notable use cases we have are: 1. Applications want to be able to implement their own external event loop and call some Winit API to poll / pump events, once per iteration of their own loop, without blocking the outer, external loop. Addressing rust-windowing#2706 2. Applications want to be able to re-run separate instantiations of some Winit-based GUI and want to allow the event loop to exit with a status, and then later be able to run the loop again for a new instantiation of their GUI. Addressing rust-windowing#2431 It's very notable that these use cases can't be supported across all platforms and so they are extensions, similar to `EventLoopExtRunReturn` The intention is to support these extensions on: - Windows - Linux (X11 + Wayland) - macOS - Android These extensions aren't compatible with Web or iOS though. Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) Once all backends have support for these extensions then we can remove `EventLoopExtRunReturn` For simplicitly, the extensions are documented with the assumption that the above platforms will be supported. This patch makes no functional change, it only introduces these new extensions so we can then handle adding platform-specific backends in separate pull requests, so the work can be landed in stages.
This adds two new extensions for running a Winit event loop which will replace `EventLoopExtRunReturn` The `run_return` API is trying to solve multiple problems and address multiple, unrelated, use cases but in doing so it is not succeeding at addressing any of them fully. The notable use cases we have are: 1. Applications want to be able to implement their own external event loop and call some Winit API to poll / pump events, once per iteration of their own loop, without blocking the outer, external loop. Addressing rust-windowing#2706 2. Applications want to be able to re-run separate instantiations of some Winit-based GUI and want to allow the event loop to exit with a status, and then later be able to run the loop again for a new instantiation of their GUI. Addressing rust-windowing#2431 It's very notable that these use cases can't be supported across all platforms and so they are extensions, similar to `EventLoopExtRunReturn` The intention is to support these extensions on: - Windows - Linux (X11 + Wayland) - macOS - Android These extensions aren't compatible with Web or iOS though. Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) Once all backends have support for these extensions then we can remove `EventLoopExtRunReturn` For simplicity, the extensions are documented with the assumption that the above platforms will be supported. This patch makes no functional change, it only introduces these new extensions so we can then handle adding platform-specific backends in separate pull requests, so the work can be landed in stages.
This adds two new extensions for running a Winit event loop which will replace `EventLoopExtRunReturn` The `run_return` API is trying to solve multiple problems and address multiple, unrelated, use cases but in doing so it is not succeeding at addressing any of them fully. The notable use cases we have are: 1. Applications want to be able to implement their own external event loop and call some Winit API to poll / pump events, once per iteration of their own loop, without blocking the outer, external loop. Addressing rust-windowing#2706 2. Applications want to be able to re-run separate instantiations of some Winit-based GUI and want to allow the event loop to exit with a status, and then later be able to run the loop again for a new instantiation of their GUI. Addressing rust-windowing#2431 It's very notable that these use cases can't be supported across all platforms and so they are extensions, similar to `EventLoopExtRunReturn` The intention is to support these extensions on: - Windows - Linux (X11 + Wayland) - macOS - Android These extensions aren't compatible with Web or iOS though. Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) Once all backends have support for these extensions then we can remove `EventLoopExtRunReturn` For simplicity, the extensions are documented with the assumption that the above platforms will be supported. This patch makes no functional change, it only introduces these new extensions so we can then handle adding platform-specific backends in separate pull requests, so the work can be landed in stages.
This adds two new extensions for running a Winit event loop which will replace `EventLoopExtRunReturn` The `run_return` API is trying to solve multiple problems and address multiple, unrelated, use cases but in doing so it is not succeeding at addressing any of them fully. The notable use cases we have are: 1. Applications want to be able to implement their own external event loop and call some Winit API to poll / pump events, once per iteration of their own loop, without blocking the outer, external loop. Addressing rust-windowing#2706 2. Applications want to be able to re-run separate instantiations of some Winit-based GUI and want to allow the event loop to exit with a status, and then later be able to run the loop again for a new instantiation of their GUI. Addressing rust-windowing#2431 It's very notable that these use cases can't be supported across all platforms and so they are extensions, similar to `EventLoopExtRunReturn` The intention is to support these extensions on: - Windows - Linux (X11 + Wayland) - macOS - Android These extensions aren't compatible with Web or iOS though. Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) Once all backends have support for these extensions then we can remove `EventLoopExtRunReturn` For simplicity, the extensions are documented with the assumption that the above platforms will be supported. This patch makes no functional change, it only introduces these new extensions so we can then handle adding platform-specific backends in separate pull requests, so the work can be landed in stages.
This adds two new extensions for running a Winit event loop which will replace `EventLoopExtRunReturn` The `run_return` API is trying to solve multiple problems and address multiple, unrelated, use cases but in doing so it is not succeeding at addressing any of them fully. The notable use cases we have are: 1. Applications want to be able to implement their own external event loop and call some Winit API to poll / pump events, once per iteration of their own loop, without blocking the outer, external loop. Addressing rust-windowing#2706 2. Applications want to be able to re-run separate instantiations of some Winit-based GUI and want to allow the event loop to exit with a status, and then later be able to run the loop again for a new instantiation of their GUI. Addressing rust-windowing#2431 It's very notable that these use cases can't be supported across all platforms and so they are extensions, similar to `EventLoopExtRunReturn` The intention is to support these extensions on: - Windows - Linux (X11 + Wayland) - macOS - Android These extensions aren't compatible with Web or iOS though. Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) Once all backends have support for these extensions then we can remove `EventLoopExtRunReturn` For simplicity, the extensions are documented with the assumption that the above platforms will be supported. This patch makes no functional change, it only introduces these new extensions so we can then handle adding platform-specific backends in separate pull requests, so the work can be landed in stages.
This adds two new extensions for running a Winit event loop which will replace `EventLoopExtRunReturn` The `run_return` API is trying to solve multiple problems and address multiple, unrelated, use cases but in doing so it is not succeeding at addressing any of them fully. The notable use cases we have are: 1. Applications want to be able to implement their own external event loop and call some Winit API to poll / pump events, once per iteration of their own loop, without blocking the outer, external loop. Addressing rust-windowing#2706 2. Applications want to be able to re-run separate instantiations of some Winit-based GUI and want to allow the event loop to exit with a status, and then later be able to run the loop again for a new instantiation of their GUI. Addressing rust-windowing#2431 It's very notable that these use cases can't be supported across all platforms and so they are extensions, similar to `EventLoopExtRunReturn` The intention is to support these extensions on: - Windows - Linux (X11 + Wayland) - macOS - Android These extensions aren't compatible with Web or iOS though. Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) Once all backends have support for these extensions then we can remove `EventLoopExtRunReturn` For simplicity, the extensions are documented with the assumption that the above platforms will be supported. This patch makes no functional change, it only introduces these new extensions so we can then handle adding platform-specific backends in separate pull requests, so the work can be landed in stages.
This adds two new extensions for running a Winit event loop which will replace `EventLoopExtRunReturn` The `run_return` API is trying to solve multiple problems and address multiple, unrelated, use cases but in doing so it is not succeeding at addressing any of them fully. The notable use cases we have are: 1. Applications want to be able to implement their own external event loop and call some Winit API to poll / pump events, once per iteration of their own loop, without blocking the outer, external loop. Addressing rust-windowing#2706 2. Applications want to be able to re-run separate instantiations of some Winit-based GUI and want to allow the event loop to exit with a status, and then later be able to run the loop again for a new instantiation of their GUI. Addressing rust-windowing#2431 It's very notable that these use cases can't be supported across all platforms and so they are extensions, similar to `EventLoopExtRunReturn` The intention is to support these extensions on: - Windows - Linux (X11 + Wayland) - macOS - Android These extensions aren't compatible with Web or iOS though. Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) Once all backends have support for these extensions then we can remove `EventLoopExtRunReturn` For simplicity, the extensions are documented with the assumption that the above platforms will be supported. This patch makes no functional change, it only introduces these new extensions so we can then handle adding platform-specific backends in separate pull requests, so the work can be landed in stages.
This adds two new extensions for running a Winit event loop which will replace `EventLoopExtRunReturn` The `run_return` API is trying to solve multiple problems and address multiple, unrelated, use cases but in doing so it is not succeeding at addressing any of them fully. The notable use cases we have are: 1. Applications want to be able to implement their own external event loop and call some Winit API to poll / pump events, once per iteration of their own loop, without blocking the outer, external loop. Addressing rust-windowing#2706 2. Applications want to be able to re-run separate instantiations of some Winit-based GUI and want to allow the event loop to exit with a status, and then later be able to run the loop again for a new instantiation of their GUI. Addressing rust-windowing#2431 It's very notable that these use cases can't be supported across all platforms and so they are extensions, similar to `EventLoopExtRunReturn` The intention is to support these extensions on: - Windows - Linux (X11 + Wayland) - macOS - Android These extensions aren't compatible with Web or iOS though. Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) Once all backends have support for these extensions then we can remove `EventLoopExtRunReturn` For simplicity, the extensions are documented with the assumption that the above platforms will be supported. This patch makes no functional change, it only introduces these new extensions so we can then handle adding platform-specific backends in separate pull requests, so the work can be landed in stages.
This adds two new extensions for running a Winit event loop which will replace `EventLoopExtRunReturn` The `run_return` API is trying to solve multiple problems and address multiple, unrelated, use cases but in doing so it is not succeeding at addressing any of them fully. The notable use cases we have are: 1. Applications want to be able to implement their own external event loop and call some Winit API to poll / pump events, once per iteration of their own loop, without blocking the outer, external loop. Addressing rust-windowing#2706 2. Applications want to be able to re-run separate instantiations of some Winit-based GUI and want to allow the event loop to exit with a status, and then later be able to run the loop again for a new instantiation of their GUI. Addressing rust-windowing#2431 It's very notable that these use cases can't be supported across all platforms and so they are extensions, similar to `EventLoopExtRunReturn` The intention is to support these extensions on: - Windows - Linux (X11 + Wayland) - macOS - Android These extensions aren't compatible with Web or iOS though. Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) Once all backends have support for these extensions then we can remove `EventLoopExtRunReturn` For simplicity, the extensions are documented with the assumption that the above platforms will be supported. This patch makes no functional change, it only introduces these new extensions so we can then handle adding platform-specific backends in separate pull requests, so the work can be landed in stages.
This adds two new extensions for running a Winit event loop which will replace `EventLoopExtRunReturn` The `run_return` API is trying to solve multiple problems and address multiple, unrelated, use cases but in doing so it is not succeeding at addressing any of them fully. The notable use cases we have are: 1. Applications want to be able to implement their own external event loop and call some Winit API to poll / pump events, once per iteration of their own loop, without blocking the outer, external loop. Addressing rust-windowing#2706 2. Applications want to be able to re-run separate instantiations of some Winit-based GUI and want to allow the event loop to exit with a status, and then later be able to run the loop again for a new instantiation of their GUI. Addressing rust-windowing#2431 It's very notable that these use cases can't be supported across all platforms and so they are extensions, similar to `EventLoopExtRunReturn` The intention is to support these extensions on: - Windows - Linux (X11 + Wayland) - macOS - Android These extensions aren't compatible with Web or iOS though. Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) Once all backends have support for these extensions then we can remove `EventLoopExtRunReturn` For simplicity, the extensions are documented with the assumption that the above platforms will be supported. This patch makes no functional change, it only introduces these new extensions so we can then handle adding platform-specific backends in separate pull requests, so the work can be landed in stages.
This adds two new extensions for running a Winit event loop which will replace `EventLoopExtRunReturn` The `run_return` API is trying to solve multiple problems and address multiple, unrelated, use cases but in doing so it is not succeeding at addressing any of them fully. The notable use cases we have are: 1. Applications want to be able to implement their own external event loop and call some Winit API to poll / pump events, once per iteration of their own loop, without blocking the outer, external loop. Addressing rust-windowing#2706 2. Applications want to be able to re-run separate instantiations of some Winit-based GUI and want to allow the event loop to exit with a status, and then later be able to run the loop again for a new instantiation of their GUI. Addressing rust-windowing#2431 It's very notable that these use cases can't be supported across all platforms and so they are extensions, similar to `EventLoopExtRunReturn` The intention is to support these extensions on: - Windows - Linux (X11 + Wayland) - macOS - Android These extensions aren't compatible with Web or iOS though. Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) Once all backends have support for these extensions then we can remove `EventLoopExtRunReturn` For simplicity, the extensions are documented with the assumption that the above platforms will be supported. This patch makes no functional change, it only introduces these new extensions so we can then handle adding platform-specific backends in separate pull requests, so the work can be landed in stages.
This adds two new extensions for running a Winit event loop which will replace `EventLoopExtRunReturn` The `run_return` API is trying to solve multiple problems and address multiple, unrelated, use cases but in doing so it is not succeeding at addressing any of them fully. The notable use cases we have are: 1. Applications want to be able to implement their own external event loop and call some Winit API to poll / pump events, once per iteration of their own loop, without blocking the outer, external loop. Addressing rust-windowing#2706 2. Applications want to be able to re-run separate instantiations of some Winit-based GUI and want to allow the event loop to exit with a status, and then later be able to run the loop again for a new instantiation of their GUI. Addressing rust-windowing#2431 It's very notable that these use cases can't be supported across all platforms and so they are extensions, similar to `EventLoopExtRunReturn` The intention is to support these extensions on: - Windows - Linux (X11 + Wayland) - macOS - Android These extensions aren't compatible with Web or iOS though. Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) Once all backends have support for these extensions then we can remove `EventLoopExtRunReturn` For simplicity, the extensions are documented with the assumption that the above platforms will be supported. This patch makes no functional change, it only introduces these new extensions so we can then handle adding platform-specific backends in separate pull requests, so the work can be landed in stages.
This adds two new extensions for running a Winit event loop which will replace `EventLoopExtRunReturn` The `run_return` API is trying to solve multiple problems and address multiple, unrelated, use cases but in doing so it is not succeeding at addressing any of them fully. The notable use cases we have are: 1. Applications want to be able to implement their own external event loop and call some Winit API to poll / pump events, once per iteration of their own loop, without blocking the outer, external loop. Addressing #2706 2. Applications want to be able to re-run separate instantiations of some Winit-based GUI and want to allow the event loop to exit with a status, and then later be able to run the loop again for a new instantiation of their GUI. Addressing #2431 It's very notable that these use cases can't be supported across all platforms and so they are extensions, similar to `EventLoopExtRunReturn` The intention is to support these extensions on: - Windows - Linux (X11 + Wayland) - macOS - Android These extensions aren't compatible with Web or iOS though. Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) Once all backends have support for these extensions then we can remove `EventLoopExtRunReturn` For simplicity, the extensions are documented with the assumption that the above platforms will be supported. This patch makes no functional change, it only introduces these new extensions so we can then handle adding platform-specific backends in separate pull requests, so the work can be landed in stages.
This adds two new extensions for running a Winit event loop which will replace `EventLoopExtRunReturn` The `run_return` API is trying to solve multiple problems and address multiple, unrelated, use cases but in doing so it is not succeeding at addressing any of them fully. The notable use cases we have are: 1. Applications want to be able to implement their own external event loop and call some Winit API to poll / pump events, once per iteration of their own loop, without blocking the outer, external loop. Addressing rust-windowing#2706 2. Applications want to be able to re-run separate instantiations of some Winit-based GUI and want to allow the event loop to exit with a status, and then later be able to run the loop again for a new instantiation of their GUI. Addressing rust-windowing#2431 It's very notable that these use cases can't be supported across all platforms and so they are extensions, similar to `EventLoopExtRunReturn` The intention is to support these extensions on: - Windows - Linux (X11 + Wayland) - macOS - Android These extensions aren't compatible with Web or iOS though. Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) Once all backends have support for these extensions then we can remove `EventLoopExtRunReturn` For simplicity, the extensions are documented with the assumption that the above platforms will be supported. This patch makes no functional change, it only introduces these new extensions so we can then handle adding platform-specific backends in separate pull requests, so the work can be landed in stages.
This adds two new extensions for running a Winit event loop which will replace `EventLoopExtRunReturn` The `run_return` API is trying to solve multiple problems and address multiple, unrelated, use cases but in doing so it is not succeeding at addressing any of them fully. The notable use cases we have are: 1. Applications want to be able to implement their own external event loop and call some Winit API to poll / pump events, once per iteration of their own loop, without blocking the outer, external loop. Addressing #2706 2. Applications want to be able to re-run separate instantiations of some Winit-based GUI and want to allow the event loop to exit with a status, and then later be able to run the loop again for a new instantiation of their GUI. Addressing #2431 It's very notable that these use cases can't be supported across all platforms and so they are extensions, similar to `EventLoopExtRunReturn` The intention is to support these extensions on: - Windows - Linux (X11 + Wayland) - macOS - Android These extensions aren't compatible with Web or iOS though. Each method of running the loop will behave consistently in terms of how `NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched (so portable application code wouldn't necessarily need to have any awareness of which method of running the loop was being used) Once all backends have support for these extensions then we can remove `EventLoopExtRunReturn` For simplicity, the extensions are documented with the assumption that the above platforms will be supported. This patch makes no functional change, it only introduces these new extensions so we can then handle adding platform-specific backends in separate pull requests, so the work can be landed in stages.
Hi!
I have noticed there are some inconsistencies (or at least it appears so) when running an event loop using
run_return
compared torun
. I have tried creating as small as possible repro example Android Activity Winit Glutin where I have taken a working example and replaced therun
withrun_return
and I cannot get the messagesResumed
orSuspended
to arrive.More specifically see this commit diff
I can get the
Resumed
event to arrive if I don't exit the loop when I getEvent::MainEventsCleared
, however that is a bit unexpected.Please let me know if I have missed something important that will make the events appear.
The text was updated successfully, but these errors were encountered: