From e894bf71a26115b03b916ebd99d6f56ccc7fa336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 10 Jun 2022 18:38:06 +0200 Subject: [PATCH] Wayland: Fix resize events before ack_configure The surface was resized and the size event was emitted before we had sent xdg_surface::ack_configure. If user code then called some GLFW function that commited the surface, those changes would all get applied to the wrong configure event. This postpones size changes until after the ack. (cherry picked from commit e33db6d7aa2b62072f312bd7b723efecf5b7c9ac) --- src/wl_platform.h | 4 +++ src/wl_window.c | 62 +++++++++++++++++++++++++++++------------------ 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/wl_platform.h b/src/wl_platform.h index b8e94295..72a695d0 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -189,6 +189,10 @@ typedef struct _GLFWwindowWayland struct wl_egl_window* native; struct wl_callback* callback; + struct { + int width, height; + } pending; + struct { struct xdg_surface* surface; struct xdg_toplevel* toplevel; diff --git a/src/wl_window.c b/src/wl_window.c index b798ec64..6010531b 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -506,8 +506,6 @@ static void xdgToplevelHandleConfigure(void* userData, struct wl_array* states) { _GLFWwindow* window = userData; - float aspectRatio; - float targetRatio; uint32_t* state; GLFWbool maximized = GLFW_FALSE; GLFWbool fullscreen = GLFW_FALSE; @@ -531,28 +529,6 @@ static void xdgToplevelHandleConfigure(void* userData, } } - if (width != 0 && height != 0) - { - if (!maximized && !fullscreen) - { - if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE) - { - aspectRatio = (float)width / (float)height; - targetRatio = (float)window->numer / (float)window->denom; - if (aspectRatio < targetRatio) - height = width / targetRatio; - else if (aspectRatio > targetRatio) - width = height * targetRatio; - } - } - - _glfwInputWindowSize(window, width, height); - window->wl.width = width; - window->wl.height = height; - resizeWindow(window); - _glfwInputWindowDamage(window); - } - if (window->wl.activated && !activated) { if (window->monitor && window->autoIconify) @@ -567,6 +543,17 @@ static void xdgToplevelHandleConfigure(void* userData, window->wl.activated = activated; window->wl.maximized = maximized; window->wl.fullscreen = fullscreen; + + if (width && height) + { + window->wl.pending.width = width; + window->wl.pending.height = height; + } + else + { + window->wl.pending.width = window->wl.width; + window->wl.pending.height = window->wl.height; + } } static void xdgToplevelHandleClose(void* userData, @@ -586,7 +573,34 @@ static void xdgSurfaceHandleConfigure(void* userData, struct xdg_surface* surface, uint32_t serial) { + _GLFWwindow* window = userData; + int width = window->wl.pending.width; + int height = window->wl.pending.height; + xdg_surface_ack_configure(surface, serial); + + if (!window->wl.maximized && !window->wl.fullscreen) + { + if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE) + { + const float aspectRatio = (float) width / (float) height; + const float targetRatio = (float) window->numer / (float) window->denom; + if (aspectRatio < targetRatio) + height = width / targetRatio; + else if (aspectRatio > targetRatio) + width = height * targetRatio; + } + } + + if (width != window->wl.width || height != window->wl.height) + { + window->wl.width = width; + window->wl.height = height; + resizeWindow(window); + + _glfwInputWindowSize(window, width, height); + _glfwInputWindowDamage(window); + } } static const struct xdg_surface_listener xdgSurfaceListener = {