Skip to content
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

Return immediately from run_app on web #4165

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

madsmtm
Copy link
Member

@madsmtm madsmtm commented Mar 17, 2025

Builds upon #4149.

Returning immediately from EventLoop::run_app on the web avoids using JavaScript exceptions, which is a huge hack that has compatibility issues, and doesn't work with the Exception Handling Proposal for WebAssembly.

This needs the application handler passed to run_app to be 'static, but that works better on iOS too anyhow (since you can't accidentally forget to pass in state that then wouldn't be dropped when terminating). This effectively reverts the decision in #3006, CC @kchibisov, do you recall if there was a deep motivation for doing that?

Since spawn_app (added in #2208) is now no longer necessary, I've removed it. This means that all the examples should work properly on web again.

  • Tested on all platforms changed
  • Added an entry to the changelog module if knowledge of this change could be valuable to users
  • Updated documentation to reflect any user-facing changes, including notes of platform-specific behavior
  • Created or updated an example program if it would help users understand this functionality

@madsmtm madsmtm added S - enhancement Wouldn't this be the coolest? S - api Design and usability DS - ios DS - web labels Mar 17, 2025
@kchibisov
Copy link
Member

I think they worked properly as well? Just we had a hack to hold the exit? In general, the point was that you might have a code that does cleanup after the exit in a cross platform manner, and thus, doing an instant return doesn't make much sense from a cross platform behavior.

The iOS model is acceptable, since you close the app anyway after so. In general, I'm leaning towards special backends just not being a part of the regular run facility at all, so the difference is clearly stated for them.

@madsmtm
Copy link
Member Author

madsmtm commented Mar 17, 2025

I think they worked properly as well? Just we had a hack to hold the exit?

The hack was "throw an exception and cross fingers that Rust doesn't see it and run destructors". Not really what I'd call "worked properly", rather "terribly UB but worked because WASM doesn't yet support exceptions".

In general, the point was that you might have a code that does cleanup after the exit in a cross platform manner, and thus, doing an instant return doesn't make much sense from a cross platform behavior.

On the web and iOS currently, having cleanup after run_app is wrong. If using spawn_app, having cleanup after is even more wrong. If we want to provide a cross-platform API here, then the user just shouldn't do anything after run_app.

The iOS model is acceptable, since you close the app anyway after so. In general, I'm leaning towards special backends just not being a part of the regular run facility at all, so the difference is clearly stated for them.

My problem is that example code suffers when we do not provide a single API that everyone can reliably use (Android is special in that it cannot be a binary, but the others do not need to suffer from this). An alternative would be to provide EventLoop::run_or_spawn_app, but that seemed unnecessary to me.

Base automatically changed from madsmtm/drop-on-exit to master March 17, 2025 09:56
@madsmtm madsmtm marked this pull request as ready for review March 17, 2025 09:56
This avoids using JavaScript exceptions to support `EventLoop::run_app`
on the web, which is a huge hack, and doesn't work with the Exception
Handling Proposal for WebAssembly:
https://github.com/WebAssembly/exception-handling

This needs the application handler passed to `run_app` to be `'static`,
but that works better on iOS too anyhow (since you can't accidentally
forget to pass in state that then wouldn't be dropped when terminating).
@madsmtm madsmtm force-pushed the madsmtm/run-app-static branch from ca7e746 to 7cbc584 Compare March 17, 2025 09:56
@kchibisov
Copy link
Member

On the web and iOS currently, having cleanup after run_app is wrong. If using spawn_app, having cleanup after is even more wrong. If we want to provide a cross-platform API here, then the user just shouldn't do anything after run_app.

Yeah, but those targets are rather special, so I don't see an issue with them being treated via their own API. Web needs special code anyway to setup canvas and such. We may change it to the way you suggest, but I'm just worrying that it could be more surprising, since I'm already not much in favor that semantics do differ.

@madsmtm
Copy link
Member Author

madsmtm commented Mar 17, 2025

An alternative would be to provide a winit_main!(|| App::default()); macro that initializes the application and runs the event loop under default settings. This would probably also be a bit nicer on Android.


As a few data points, Bevy is already effectively merging run_app and spawn_app, so is Iced. Masonry/Xilem isn't using spawn_app, though they do support web (so they get the worse behaviour), same with ggez. eframe uses just run_app, but their web impl bypasses Winit anyhow.

My point is that all of these examples would benefit from this PR.

@madsmtm
Copy link
Member Author

madsmtm commented Mar 17, 2025

I'm just worrying that it could be more surprising, since I'm already not much in favor that semantics do differ.

I do somewhat agree here, the differing semantics are confusing (I've tried to remediate this with better documentation), though I guess my point is that to most users it probably won't matter (either they only support desktop, and then they don't care, or they also support web, in which case they'll have tested their app there and seen that it does indeed work as they expect).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DS - ios DS - web S - api Design and usability S - enhancement Wouldn't this be the coolest?
Development

Successfully merging this pull request may close these issues.

2 participants