Skip to content
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

Process pending resize events before sizing viewport on startup #2450

Closed
wants to merge 1 commit into from

Conversation

Xyene
Copy link

@Xyene Xyene commented Mar 19, 2020

Addresses #2447.

This commit processes pending resize events after glfwCreateWindow, so that glfwGetFramebufferSize returns the correct size for viewport sizing.

This fixes flickering visible when starting kitty in a tiling window manager like sway.

I've imported glfwPollEvents and supporting functions from glfw master.

@kovidgoyal
Copy link
Owner

This is not safe to do. Calling pollevents inside the function that creates a window means that some random callback that depend on a fully initialized window could be called, leading to bad things.

@kovidgoyal
Copy link
Owner

Do you notice the flicker when creating secondary OS windows in the same kitty instance, with ctrl+shift+n?

@Xyene
Copy link
Author

Xyene commented Mar 19, 2020

Agreed on safety, though I figured it would've been fine here since it's being called prior to installing callbacks on the window, and the GIL is still held on the Python side so there's nothing that could enumerate the window before we return. Is this understanding wrong?

The issue is present in single-instance mode as well. The issue's cause is that glfwCreateWindow is called with 640x480, the window is actually created with size 640x480 and then immediately resized to the correct size of the tile. This hops through the Python side Window.set_geometry twice, once with a wrong geometry.

@kovidgoyal
Copy link
Owner

kovidgoyal commented Mar 19, 2020 via email

@Xyene
Copy link
Author

Xyene commented Mar 19, 2020

And this is rather fragile as well, since it could change in the future, and whoever changes it would need to remember to ensure that this invariant does not change.

Agreed.

Isn't this fundamentally race-y though?

Yes :)

There is no guarantee that will happen, and I suspect if your system is under load it will definitely not happen.

Anecdotally, it happens reliably on my machine even with all cores pegged to 100% via stress. I imagine the WM sends the resize event immediately. The failure condition when the resize event isn't received in time isn't catastrophic, it just degrades the visual output to what is currently the default behaviour. I suppose it comes down to if you want to have a hack supporting a quality-of-life improvement or not.

Concurrently with opening this PR, I asked around in #sway-devel whether the resize event was in any way sent "atomically" at window creation time. The answer I got was no, and that the underlying issue is swaywm/sway#2176 — unfortunately, that issue hasn't seen activity since 2018.

That said, kitty is one of very few Wayland-native applications that aren't slow, so I imagine quality-of-life improvements might go a long way. I can understand if you don't wish to have a hack like this in place (using a tiling WM on Wayland seems like a niche within a niche), and am satisfied with simply applying it locally whenever I update kitty, but it does seem generally useful for those in that niche.

I was curious to see what alacritty does, since it doesn't have visual glitches on startup. It seems they just handle the resize event normally, and somehow there are no glitches. I don't imagine the Python bit of kitty would be slow enough to add up to ~100ms per resize, but since alacritty doesn't use GLFW I don't think there's any immediately useful information to gain from there.

@kovidgoyal
Copy link
Owner

kovidgoyal commented Mar 19, 2020 via email

@Xyene
Copy link
Author

Xyene commented Mar 19, 2020

Alright, here's another take on it based on the discussion: on Wayland, wait 5ms for any resize events to appear before returning from glfwCreateWindow. At this point we will have no callbacks installed, and it seems harder to accidentally mess things up in the future.

This seems to actually work better than the original PR, since it also eliminates the first "stage" from the linked issue, whereas before only the second, more visible, glitch would be hidden. (I think because it gets in before glfwSwapBuffers?) 5ms seems like a good trade-off, in the frequent case where it avoids a ~100ms resize.

Addresses kovidgoyal#2447.

This commit processes pending resize events after the bulk of
`glfwCreateWindow`, so that `glfwGetFramebufferSize` returns the
correct size for viewport sizing.

This fixes flickering visible when starting kitty in a tiling window
manager like sway.
@emersion
Copy link

This is caused by a Sway bug I believe: swaywm/sway#2176

Please don't merge any Sway workarounds in Kitty. Sway bugs ought to be fixed in Sway, not in each and every client.

@Xyene
Copy link
Author

Xyene commented Mar 19, 2020

Since @emersion is a major contributor to Sway and objects to this patch, I'll honor their wishes and close this PR. Until such a time when the Sway bug is fixed, I suppose anyone else encountering this issue who searches the issue tracker will find this patch easy enough to apply.

@Xyene Xyene closed this Mar 19, 2020
@kovidgoyal
Copy link
Owner

I agree that we should avoid compositor specific workarounds as far as possible. That said, I was thinking about this (in the shower) and it occurs to me that kitty already uses the mechanism for requesting render frames from the compositor and only renders after receiving one (grep for USE_RENDER_FRAMES). Assuming the compositor sends the initial resize event before the first render frame, it may be possible to refactor the main loop a bit to ensure the resize event is fully processed before rendering.

@kovidgoyal
Copy link
Owner

Although I guess reading the sway bug, it wont work, since sway only sends the correct size after the first render.

@Xyene
Copy link
Author

Xyene commented Mar 20, 2020

I guess it's alright, at the end of the day it's just another patch to maintain locally, but I already have so many for fixing random problems in programs I use that one more isn't a big deal. Thanks for your time in reviewing this PR, though :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants