-
Notifications
You must be signed in to change notification settings - Fork 924
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
Erroneous WindowEvent::Resized
sent on app startup
#2094
Comments
I am seeing the same behavior after switching from 0.25 to 0.26. A workaround is to ignore resize events when the start cause in |
Seems related to 3ecbea3. I did not confirm that though... |
I am getting:
With a native physical size of 3840 x 2160. The first resize seems random and has no obvious relation to the native size. |
PS : the first size might come from Windows 10 default window size. |
My initial assumption would be that due to moving parts from |
It's definitely related to splitting the window creation across winit/src/platform_impl/windows/window.rs Lines 810 to 821 in 438d286
The I'm still a little surprised by the fact that there are still multiple |
I thought that the comment above |
Decorations appear fine when drawing something on the screen, which the |
I'm using wgpu (with Vulkan backend) with winit on Windows. let event_loop = EventLoop::new();
// the following line will call CreateWindowA with CW_USEDEFAULT as width and height. Windows will choose an initial size
let window = WindowBuilder::new().with_inner_size(winit::dpi::PhysicalSize{width: 800, height: 600}).build(&event_loop).unwrap();
// so Windows thinks the window inner size is (2862, 1510), but winit thinks it (800, 600). (i'm using 3840x2160 monitor with scale factor 1.25)
setup_wgpu(); // vulkan will complains here because of the inconsistency
// event_loop.run() will resize the window on WM_CREATE / WM_NCCREATE
event_loop.run(call_back); The inner size is inconsistent between Window::new() and event_loop.run(). I can see the window has a big initial size and then flashes to 800x600 and Vulkan validation layer complains about it. I propose winit to set window size on CreateWindowA() instead of postpone it until event_loop.run(). |
I see the same behaviour (basically) on Wayland:
|
Could you provide WAYLAND_DEBUG logs? |
Scale factors 100% and 150%: |
Are you sure that you've reproduced your issue in log with scale 1.5? Could you provide interleaved log from winit and from WAYLAND_DEBUG=1 during you reproducing the issue? I have a guess what the problem is, but this particular log looks fine to me. |
Hopefully this is better? Not sure what you mean by the winit log since it doesn't appear to have one (here I enabled trace level but minimised the noisy stuff):
|
@dhardy Seems like gnome( I guess it's gnome) decided to resize you, nothing we can do here?
|
KDE/kwin actually. The real question is not so much why the compositor resized the window on Alt+Tab but why it resized it after construction:
The |
On Wayland all windows are created at scale factor one, and then got resized/rescaled to other scale factor. The resize is expected. See https://gitlab.freedesktop.org/wayland/wayland/-/issues/133. |
Max size and min size are in window geometry coordinates. So they are logical. |
But the behaviour I see is that the window is too large on construction, but the correct size after Alt+Tab. Hence |
In fact, the KAS toolkit "cheats" by looking up the scale factor from the previous window constructed or (initially) from the list of available screens, thus it calculates the size requirements (using physical pixels internally) using scale factor 2. It sounds like Wayland assumes the window size will be calculated in logical pixels. Thus the issue is probably that winit accepts size requests through |
You don't know scale factor your window will use even if you probe all monitors. You can't just assume that it's 2, you should use 1, and wait for ScaleFactorChanged. |
But yeah, wayland is entirely in logical pixels, only buffer size is physical. |
No, but I can guess. If I remember correctly, I wrote this code to make the initial size correct on X11. Can't I get both right? The way I see it, it's currently undefined (or improperly documented) how sizes passed in physical or logical pixels (dependant on the platform) are handled before the window's scale factor is known. |
If you provide size in logical pixels you should get correct window size regarding on window scale factor? Since on X11 I bet it can know that it's 2. The problem is that creating window in physical pixels as well as using physical pixels is unreliable and overly complicated, I'd say. |
The thing winit's Wayland backend is doing makes sense to me, since it converts your size to logical size with a scale factor surface has right now. If you've passed the physical size computed for scale factor 2 you're out of luck, since winit knows scale factor 1, not 2. And logical is required, since Wayland's window API is entirely in logical pixels. |
So, on X11, using my scale-factor-detection methodology and physical pixels:
And the result looks correct. Instead using scale-factor=1 to calculate sizes and passing as logical sizes:
The window that appears is too small and does not ever get resized. So, possibly the X11 implementation should be doing the scaling, or at least sending But from my perspective it's wrong, as I've been been arguing here: neither winit nor a compositor can accurately calculate the scaled size since e.g. if a line of text would be 20.6 pixels tall, that needs to be rounded to an integer, then that integer size used to calculate the y-position of the next line, etc., thus when a window is sized to its contents, only the toolkit can calculate the correct window size. |
Apparently I made a mistake above: after the window is constructed, the render scale factor is known, and the toolkit can re-calculate layout using that immediately:
The result looks acceptable, though the size is not exactly what was requested... edit: the resize happens because once the layout is recalculated, the toolkit calculates a different (smaller) ideal size for some reason, and calls |
@dhardy if you follow the logic wrt startup size and initial DPI are we doing in alacritty will it work for you (https://github.com/alacritty/alacritty/blob/589c1e9c6b8830625162af14a9a7aee32c7aade0/alacritty/src/display/mod.rs#L227) ? |
Yes, that's about what I just came up with. |
Hit this issue in our project, ended up working around it with roughly this code: let mut is_init = false;
event_loop.run(move |event, _, control_flow| {
match event {
Event::WindowEvent {
event: WindowEvent::Resized(size),
..
} => {
if is_init {
return;
}
if size.width != 0 || size.height != 0 {
actually_do_resize(size.width, size.height);
}
}
Event::NewEvents(cause) => {
if cause == StartCause::Init {
is_init = true;
} else {
is_init = false;
}
}
// ...
}
}); This fixes the issue on Windows 10 at least. |
I'm seeing this issue on Gnome/X11. In my case, I'm getting another resize event with the correct size right after, so the following fix works: let mut new_size = None;
event_loop.run(move |event, _, control_flow| {
match event {
Event::WindowEvent {
event: WindowEvent::Resized(size),
..
} => {
new_size = Some(size);
}
Event::RedrawRequested(_) => {
if let Some(size) = new_size.take() {
renderer.handle_resize(size);
}
// ...
}
_ => {}
}
}); |
I am also seeing this on Windows 10. I'm building my window: let window_builder = WindowBuilder::new()
.with_inner_size(PhysicalSize {
width: 800,
height: 600,
})
//... and then I see three resize events after running the event loop:
|
Is there any movement on this bug on Windows? The workaround above doesn't seem to work for me on Windows 11. I am getting the I suspect the original size is coming from using |
The current work around I have is something like this: #[cfg(windows)]
let mut is_init = false;
#[cfg(not windows)]
let mut is_init = true;
event_loop.run(...
// Within WindowEvent::Resized:
if is_init {
// Do your resize
} else {
is_init = true;
}
); |
Why is the window being resized to near-full-screen and then back to the original value on application startup?
This can be reproduced with the
window
example:Platform: Windows 10
This behavior can also be observed in the
wgpu
examples (which report vulkan validation errors if you have debug logging enabled).The text was updated successfully, but these errors were encountered: