Skip to content

Reduce usage of PrimaryWindow #18362

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

Open
3 tasks
madsmtm opened this issue Mar 17, 2025 · 4 comments
Open
3 tasks

Reduce usage of PrimaryWindow #18362

madsmtm opened this issue Mar 17, 2025 · 4 comments
Labels
A-Windowing Platform-agnostic interface layer to run your app in C-Bug An unexpected or incorrect behavior C-Tracking-Issue An issue that collects information about a broad development initiative

Comments

@madsmtm
Copy link
Contributor

madsmtm commented Mar 17, 2025

Bevy has multi-window support by modelling each window as an entity, and then (heavily handwaving) delegating to Winit for the rest. The user can then choose:

  • To create two cameras for their scene, and assign it to different windows.
  • To create sub-apps to get a new World, to allow e.g. running multiple instances of their game (not really supported yet, but I assume this is roughly how we'd go about it).

This is all great, but unfortunately, some functionality uses the PrimaryWindow to implement their windowing. This is basically never desired, as it locks that piece of functionality to only being available in a single window. This issue is intended to track removing instances of this, to improve multi-window support.

I've condensed the usages of PrimaryWindow to essentially the following:

  • bevy_render::camera::RenderTarget::normalize should be changed to not need the primary window. Affects bevy_core_pipeline, bevy_picking, bevy_sprite and bevy_ui.
  • bevy_input_focus::InputFocus (and possibly InputFocusVisible) should be made Components on the window Entity instead of Resources. Affects bevy_winit's ability to update accessibility nodes.
  • bevy_text: , seems to be a remnant of Support window independent UI scaling #5621.

A few previous efforts in this vein:

To be clear: I'm not advocating we get rid of PrimaryWindow, it can be useful for the user, and it's useful for controlling the close behaviour in bevy_window (also discussed in #13698). But we should avoid using it internally in Bevy (perhaps even add it as a Clippy disallowed-types?).

@madsmtm madsmtm added A-Windowing Platform-agnostic interface layer to run your app in C-Bug An unexpected or incorrect behavior S-Needs-Triage This issue needs to be labelled labels Mar 17, 2025
@madsmtm
Copy link
Contributor Author

madsmtm commented Mar 17, 2025

@viridia is there a reason why bevy_input_focus::InputFocus is a resource and not a Window-local component?

And API-wise there, would y'all prefer a required InputFocus(Option<Entity>) component on Window, or InputFocus(Entity) that can be added/removed.
(Where the None/not present here signifies that nothing has focus, and the event should be delivered to the Window itself).

Or perhaps: A required InputFocus(Entity), which defaults to Entity = window entity (if that's technically possible).

@ickshonpe ickshonpe removed the S-Needs-Triage This issue needs to be labelled label Mar 18, 2025
@viridia
Copy link
Contributor

viridia commented Mar 18, 2025

The question, as posed, seems kind of abstract - do you have a concrete use case in mind?

I'll be honest, in all my years of playing and making games, I have never experienced a game that used more than one window, so it's hard for me to know exactly how multiple windows ought to behave in a game context. However, I have used non-game productivity apps that had more than one window. In these cases, there was only one input focus - that is, only one window could have focus at a time, and only one widget within that window could have focus. So it makes sense to me that input focus would be a singleton.

Focus behavior isn't really something that applications are supposed to make up for themselves; rather, it's part of the general user interface guidelines for the operating system (the Macintosh Computer Interface Guidelines had a long chapter on this, however that book is no longer in print). And most operating systems assume that there is one keyboard input device active at any given time, or at the very least, if there are multiple keyboard input devices (like a separate numpad) they are all being controlled by the same user.

Mostly I tried to model things on the browser / JavaScript APIs for managing focus, since that's what I know best.

The usage of PrimaryWindow is a bit trickier here: mainly it's only meant to be used as a fallback when no widget has focus, so we have somewhere to bubble events to. However, it could also be changed to use whichever window has focus; but at the time I did not know how to get that information from winit.

@madsmtm madsmtm added the C-Tracking-Issue An issue that collects information about a broad development initiative label Mar 18, 2025
@madsmtm
Copy link
Contributor Author

madsmtm commented Mar 19, 2025

I think my point with making focus window-relative is that when switching between windows (e.g. two text-boxes in two Firefox windows), you want to keep whatever item is focused focused, regardless of the window itself loosing focus.

But perhaps I'm misunderstanding the design of bevy_input_focus?

In any case, you're correct that multi-window support is rare in games.

@viridia
Copy link
Contributor

viridia commented Mar 19, 2025

Preserving focus when switching windows is a reasonable thing to want, I agree.

However, making focus a non-global puts a heavy burden on widget authors. Most widgets just want to know, "am I focused or not?" so that they can draw themselves differently when that is true. Widgets don't generally have knowledge of what window contains them, to answer the question "am I focused" they would need to walk up the hierarchy, find the target camera component, use that to look up the window, etc. This makes it a lot more complicated.

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 C-Tracking-Issue An issue that collects information about a broad development initiative
Projects
None yet
Development

No branches or pull requests

3 participants