Repository navigation
Description
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::normalizeshould be changed to not need the primary window. Affectsbevy_core_pipeline,bevy_picking,bevy_spriteandbevy_ui. -
bevy_input_focus::InputFocus(and possiblyInputFocusVisible) should be madeComponents on the windowEntityinstead ofResources. Affectsbevy_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:
- Support window independent UI scaling #5621
- Camera-driven UI #10559
- UI outline geometry is always resolved using the size of the
PrimaryWindowregardless of target #14945
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?).
Activity
madsmtm commentedon Mar 17, 2025
@viridia is there a reason why
bevy_input_focus::InputFocusis a resource and not aWindow-local component?And API-wise there, would y'all prefer a required
InputFocus(Option<Entity>)component onWindow, orInputFocus(Entity)that can be added/removed.(Where the
None/not present here signifies that nothing has focus, and the event should be delivered to theWindowitself).Or perhaps: A required
InputFocus(Entity), which defaults toEntity = window entity(if that's technically possible).viridia commentedon 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 commentedon 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 commentedon 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.
Freyja-moth commentedon Dec 25, 2025
Wouldn't it be possible to store an
InputFocuson each window and then copy that to theInputFocusresource whenever the focused window is changed?