Skip to content

Conversation

@kristoff3r
Copy link
Contributor

@kristoff3r kristoff3r commented Dec 11, 2025

Objective

Fixes #21948

Currently we tell winit to spawn any new Windows during the about_to_wait lifecycle method, but that's unreliable: if no new events appear while we're already waiting it could take an arbitrarily long time, or no new events could appear at all so we never spawn the window. This is especially bad when going from 0 to 1 Windows, as many events are related to the existing window.

Solution

Check for new windows in resumed for the initial window (which is also what winit examples do) and in user_event for new windows.

I also did some other improvements while I was investigating this:

  • Inlined the Added<Window> query filter into CreateWindowParams, as the logic didn't make sense with any other filter.
  • Insert the EventLoopProxyWrapper resource when the plugin builds instead of inside the winit_runner. This currently makes no practical difference, but in another version of this PR I had a crash because the observer tried to use the resource before the runner started. It's also a more natural way to do it.
  • Made WinitPlugin no longer generic, and removed the custom_user_event example. The functionality it provides (being able to send events into bevy from the outside) only works in one direction, and I don't see why it needs to go via winit instead of a dedicated plugin with channels. If this feature is useful for reasons I've missed then I'm happy to re-add it. edit: winit is removing custom user events in 0.31, which made me even more confident it's the right direction for us too.

Testing

Run different examples and see that the window spawns in a timely fashion, edit the multiple_windows example as in #21948 and see that the window spawns.

@kristoff3r kristoff3r added C-Bug An unexpected or incorrect behavior A-Windowing Platform-agnostic interface layer to run your app in D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Dec 11, 2025
@IceSentry
Copy link
Contributor

I think, if possible, the change to remove all the custom_user_event and generic stuff should be in a separate PR. The main reason for this is if we ever find a user that does need it then it's easier to only revert that change instead of all your changes together.

@kristoff3r
Copy link
Contributor Author

I think, if possible, the change to remove all the custom_user_event and generic stuff should be in a separate PR. The main reason for this is if we ever find a user that does need it then it's easier to only revert that change instead of all your changes together.

That's not easily possible, this change uses the generic in EventLoop<T> to send internal messages now. Keeping the custom_user_event functionality would mean stuffing the user generic inside the new WinitUserMessage enum.

@IceSentry
Copy link
Contributor

Ah, your comment said you were happy to re-add it so I interpreted that as being easy to do 😅

@kristoff3r
Copy link
Contributor Author

Ah, your comment said you were happy to re-add it so I interpreted that as being easy to do 😅

It is easy, but it would have to build on top of this PR, as the 2 things conflict. I'd prefer if we figure out what we want first so I can make this PR do it, instead of having 2 conflicting PRs.

@kristoff3r
Copy link
Contributor Author

winit apparently agrees with me, as they have also removed the generic user messages in the beta for version 0.31, see https://github.com/rust-windowing/winit/blob/master/winit/src/changelog/v0.31.md?plain=1#L77

Copy link
Contributor

@IceSentry IceSentry left a comment

Choose a reason for hiding this comment

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

Alright, well, I can't think of a reason to keep it anyway so LGTM.

This needs a migration guide though

Copy link
Contributor

@atlv24 atlv24 left a comment

Choose a reason for hiding this comment

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

nice improvement

Copy link
Member

@tychedelia tychedelia left a comment

Choose a reason for hiding this comment

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

Thanks, this code is always gnarly.

@tychedelia tychedelia requested a review from IceSentry December 16, 2025 02:01
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Dec 16, 2025
Merged via the queue into bevyengine:main with commit 61a4645 Dec 16, 2025
40 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Windowing Platform-agnostic interface layer to run your app in C-Bug An unexpected or incorrect behavior D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Needs-Review Needs reviewer attention (from anyone!) to move forward

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Spawning Windows partially fails when there is no inital PrimaryWindow

5 participants