rust-windowing / winit

Window handling library in pure Rust
https://docs.rs/winit/
Apache License 2.0
4.67k stars 880 forks source link

Feature request: X11 Clean Resizing (aka support _NET_WM_SYNC_REQUEST) #2153

Closed Matthew-Chidlow closed 1 month ago

Matthew-Chidlow commented 2 years ago

I am trying to write a desktop application that uses Winit for windowing, with Vulkan for rendering (though that should be irrelevant).

A limitation I am facing is that on linux, when the window is resized the image appears to jigger (most notably when reszing from top left). This occurs because x11 completes the resize before getting a chance to draw a new frame of the new size.

A Gif (Note the background flickers a bit) ![jitter](https://user-images.githubusercontent.com/35484342/149561679-21365ae2-4fc7-4e90-8cde-b04bf0eadf0b.gif)

(My code for this comes from running the sandbox example here)

On Windows this is solved (properly?) by blocking the event loop when receiving a WindowEvent::Resized event until a separate thread has created a new VkSwapchain and completed drawing a new frame.

This same approach does not work on x11 due to it's apparent asynchronous behavior, instead while the event loop is blocked the window continues to resize. It is possible to recreate the behavior of Windows on x11 as noted in this Qt blog post with corresponding commit.

As far as I know, without this feature it's just not really possible to create an application with smooth resizing on x11.

For an API, possibly just a new option when building a window like .with_force_block_resize(bool) to make it so that on x11 (maybe other platforms too) blocking WindowEvent::Resized events for that window, blocks the window from resizing to mimic the Windows behavior. If this is exposed on Windows then false can't really revert the behaviour hence the use of force in the function name. This would probably be best like this as an opt, as just like the Qt blog notes, if you block for too long it can cause the resizing to seem unresponsive.

Speykious commented 1 month ago

If it can be of any help, here's some relevant documentation on X11 frame synchronization.

And here's a gist using _NET_WM_SYNC_REQUEST to get smooth resizing. It has at least one small bug I'm aware of that's mentioned in it (actually that bug wasn't related to it at all.) It's best to test it on various DEs and WMs. I have no clue what else would be needed, besides maybe more advanced synchronization as mentioned in the documentation link I gave above, since I'm kind of navigating in rough unfamiliar waters when it comes to X11, especially with the lack of documentation...

notgull commented 1 month ago

I believe this issue is fixed as of #3771, but please test and make sure it is okay on your end @Matthew-Chidlow