Wayland: Ensure that opengl buffer swapping does not happen till the xdg surface is configured

This commit is contained in:
Kovid Goyal 2022-06-28 10:47:33 +05:30
parent 72dfa74b3e
commit cd369f633a
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
7 changed files with 18 additions and 2 deletions

1
glfw/glfw3.h vendored
View File

@ -2768,6 +2768,7 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share); GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share);
GLFWAPI bool glfwToggleFullscreen(GLFWwindow *window, unsigned int flags); GLFWAPI bool glfwToggleFullscreen(GLFWwindow *window, unsigned int flags);
GLFWAPI bool glfwIsFullscreen(GLFWwindow *window, unsigned int flags); GLFWAPI bool glfwIsFullscreen(GLFWwindow *window, unsigned int flags);
GLFWAPI bool glfwAreSwapsAllowed(const GLFWwindow* window);
/*! @brief Destroys the specified window and its context. /*! @brief Destroys the specified window and its context.
* *

1
glfw/internal.h vendored
View File

@ -441,6 +441,7 @@ struct _GLFWwindow
bool rawMouseMotion; bool rawMouseMotion;
_GLFWcontext context; _GLFWcontext context;
bool swaps_disallowed;
struct { struct {
GLFWwindowposfun pos; GLFWwindowposfun pos;

4
glfw/window.c vendored
View File

@ -1067,6 +1067,10 @@ GLFWAPI bool glfwIsFullscreen(GLFWwindow* wh, unsigned int flags) {
return _glfwPlatformIsFullscreen((_GLFWwindow*)wh, flags); return _glfwPlatformIsFullscreen((_GLFWwindow*)wh, flags);
} }
GLFWAPI bool glfwAreSwapsAllowed(const GLFWwindow* wh) {
return !(((_GLFWwindow*)wh)->swaps_disallowed);
}
GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer) GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;

3
glfw/wl_window.c vendored
View File

@ -497,6 +497,7 @@ static void xdgSurfaceHandleConfigure(void* data,
if (!window->wl.surface_configured_once) { if (!window->wl.surface_configured_once) {
window->wl.surface_configured_once = true; window->wl.surface_configured_once = true;
// this will attach the buffer to the surface, the client is responsible for clearing the buffer to an appropriate blank // this will attach the buffer to the surface, the client is responsible for clearing the buffer to an appropriate blank
window->swaps_disallowed = false;
window->context.swapBuffers(window); window->context.swapBuffers(window);
if (!width && !height && !new_states && !window->wl.decorations.serverSide && getenv("XAUTHORITY") && strstr(getenv("XAUTHORITY"), "mutter")) { if (!width && !height && !new_states && !window->wl.decorations.serverSide && getenv("XAUTHORITY") && strstr(getenv("XAUTHORITY"), "mutter")) {
@ -787,6 +788,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
initialize_csd_metrics(window); initialize_csd_metrics(window);
window->wl.transparent = fbconfig->transparent; window->wl.transparent = fbconfig->transparent;
strncpy(window->wl.appId, wndconfig->wl.appId, sizeof(window->wl.appId)); strncpy(window->wl.appId, wndconfig->wl.appId, sizeof(window->wl.appId));
window->swaps_disallowed = true;
if (!createSurface(window, wndconfig)) if (!createSurface(window, wndconfig))
return false; return false;
@ -1066,6 +1068,7 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
window->wl.xdg.toplevel = NULL; window->wl.xdg.toplevel = NULL;
window->wl.xdg.surface = NULL; window->wl.xdg.surface = NULL;
window->wl.surface_configured_once = false; window->wl.surface_configured_once = false;
window->swaps_disallowed = true;
} }
window->wl.visible = false; window->wl.visible = false;
} }

3
kitty/glfw-wrapper.c generated
View File

@ -119,6 +119,9 @@ load_glfw(const char* path) {
*(void **) (&glfwIsFullscreen_impl) = dlsym(handle, "glfwIsFullscreen"); *(void **) (&glfwIsFullscreen_impl) = dlsym(handle, "glfwIsFullscreen");
if (glfwIsFullscreen_impl == NULL) fail("Failed to load glfw function glfwIsFullscreen with error: %s", dlerror()); if (glfwIsFullscreen_impl == NULL) fail("Failed to load glfw function glfwIsFullscreen with error: %s", dlerror());
*(void **) (&glfwAreSwapsAllowed_impl) = dlsym(handle, "glfwAreSwapsAllowed");
if (glfwAreSwapsAllowed_impl == NULL) fail("Failed to load glfw function glfwAreSwapsAllowed with error: %s", dlerror());
*(void **) (&glfwDestroyWindow_impl) = dlsym(handle, "glfwDestroyWindow"); *(void **) (&glfwDestroyWindow_impl) = dlsym(handle, "glfwDestroyWindow");
if (glfwDestroyWindow_impl == NULL) fail("Failed to load glfw function glfwDestroyWindow with error: %s", dlerror()); if (glfwDestroyWindow_impl == NULL) fail("Failed to load glfw function glfwDestroyWindow with error: %s", dlerror());

4
kitty/glfw-wrapper.h generated
View File

@ -1751,6 +1751,10 @@ typedef bool (*glfwIsFullscreen_func)(GLFWwindow*, unsigned int);
GFW_EXTERN glfwIsFullscreen_func glfwIsFullscreen_impl; GFW_EXTERN glfwIsFullscreen_func glfwIsFullscreen_impl;
#define glfwIsFullscreen glfwIsFullscreen_impl #define glfwIsFullscreen glfwIsFullscreen_impl
typedef bool (*glfwAreSwapsAllowed_func)(const GLFWwindow*);
GFW_EXTERN glfwAreSwapsAllowed_func glfwAreSwapsAllowed_impl;
#define glfwAreSwapsAllowed glfwAreSwapsAllowed_impl
typedef void (*glfwDestroyWindow_func)(GLFWwindow*); typedef void (*glfwDestroyWindow_func)(GLFWwindow*);
GFW_EXTERN glfwDestroyWindow_func glfwDestroyWindow_impl; GFW_EXTERN glfwDestroyWindow_func glfwDestroyWindow_impl;
#define glfwDestroyWindow glfwDestroyWindow_impl #define glfwDestroyWindow glfwDestroyWindow_impl

View File

@ -826,7 +826,7 @@ create_os_window(PyObject UNUSED *self, PyObject *args, PyObject *kw) {
if (is_first_window) glfwSwapInterval(OPT(sync_to_monitor) && !global_state.is_wayland ? 1 : 0); if (is_first_window) glfwSwapInterval(OPT(sync_to_monitor) && !global_state.is_wayland ? 1 : 0);
#endif #endif
// On Wayland the initial swap is allowed only after the first XDG configure event // On Wayland the initial swap is allowed only after the first XDG configure event
if (!global_state.is_wayland) glfwSwapBuffers(glfw_window); if (glfwAreSwapsAllowed(glfw_window)) glfwSwapBuffers(glfw_window);
glfwSetInputMode(glfw_window, GLFW_LOCK_KEY_MODS, true); glfwSetInputMode(glfw_window, GLFW_LOCK_KEY_MODS, true);
PyObject *pret = PyObject_CallFunction(pre_show_callback, "N", native_window_handle(glfw_window)); PyObject *pret = PyObject_CallFunction(pre_show_callback, "N", native_window_handle(glfw_window));
if (pret == NULL) return NULL; if (pret == NULL) return NULL;
@ -1343,7 +1343,7 @@ is_mouse_hidden(OSWindow *w) {
void void
swap_window_buffers(OSWindow *os_window) { swap_window_buffers(OSWindow *os_window) {
glfwSwapBuffers(os_window->handle); if (glfwAreSwapsAllowed(os_window->handle)) glfwSwapBuffers(os_window->handle);
} }
void void