Skip to content

fix: process window position before size in changed_windows#23248

Merged
mockersf merged 1 commit intobevyengine:mainfrom
natepiano:fix/position-before-size-v0.19
Mar 9, 2026
Merged

fix: process window position before size in changed_windows#23248
mockersf merged 1 commit intobevyengine:mainfrom
natepiano:fix/position-before-size-v0.19

Conversation

@natepiano
Copy link
Contributor

@natepiano natepiano commented Mar 6, 2026

Summary

When a bevy app starts, winit creates the window on a default monitor. If the app then sets the window's position to a location on a different monitor with a different scale factor, both position and size may be applied in the same pass through changed_windows().

Currently, size is processed first (via request_inner_size), then position (via set_outer_position). Since the window hasn't moved yet when request_inner_size runs, it uses the default monitor's scale factor for the size calculation — not the scale factor of the monitor the window is about to move to. This produces the wrong size when the two monitors have different scale factors.

This PR moves the position block above the size block so the window is on the target monitor before request_inner_size runs.

Context

This change is a no-op with current released versions of winit. Today, winit's set_outer_position has a bug where it uses the window's current monitor's scale factor instead of the target monitor's (rust-windowing/winit#4505), so the window doesn't reliably land at the correct position regardless of ordering.

Once winit merges that fix and bevy takes a dependency on a version that includes it, the ordering will matter: set_outer_position will correctly move the window to the target monitor, and request_inner_size needs to run after that move so it sees the correct scale_factor().

The change is safe and backwards-compatible — it just reorders two independent blocks within the same function.

Testing

Tested on macOS (1x + 2x) and Windows (1x + 1.5x) with the patched winit. Window appears at the correct position and size on the target monitor.

Move the position block above the resolution block so the window is on
the correct monitor (and scale_factor() returns the target monitor's
value) before request_inner_size runs.

This is a prerequisite for the winit fix to set_outer_position's scale
factor resolution (rust-windowing/winit#4440).
@natepiano
Copy link
Contributor Author

note from my PR to winit:

I did not apply this fix to the X11 backend. X11 typically reports the same scale factor for all monitors (via the global Xft.dpi setting), so the bug does not manifest in practice.

note i didn't provide to winit

Wayland doesn't matter - can't set position on Wayland

@kfc35 kfc35 added A-Windowing Platform-agnostic interface layer to run your app in D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Needs-Review Needs reviewer attention (from anyone!) to move forward C-Bug An unexpected or incorrect behavior labels Mar 7, 2026
@Lampan-git
Copy link
Contributor

Wayland doesn't matter - can't set position on Wayland

Isn't this solved by the recently merged xx-zones PR: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/264?

@natepiano
Copy link
Contributor Author

well well - i had no idea - i wonder when that will make its way into the distribution i test with (asahi running on a partition on my m2 mac). I would definitely love to be able to relax / remove special casing for wayland in my code. As i'm parsing your link - it seems that this is an experimental feature you have to enable. I'm a linux beginner so don't know how to get this to work or test for its existence. Any pointers?

Regardless - even though i didn't test this on Wayland, it should still be a no-op for wayland right now just as it is for everything else I tested - and it's only a net positive for wayland as well after winit merges (rust-windowing/winit#4505) for anyone that has the experimental wayland positioning turned on.

Thanks for the link.

@Lampan-git
Copy link
Contributor

I'm not that well versed with Wayland tbh, thought I would just highlight it. You can see which compositors support it here though: https://wayland.app/protocols/xx-zones-v1#compositor-support, which is none right now.

@alice-i-cecile alice-i-cecile added the X-Uncontroversial This work is generally agreed upon label Mar 9, 2026
@mockersf mockersf added this pull request to the merge queue Mar 9, 2026
Merged via the queue into bevyengine:main with commit 4ad55b0 Mar 9, 2026
49 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-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Needs-Review Needs reviewer attention (from anyone!) to move forward X-Uncontroversial This work is generally agreed upon

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants