From 39e75e39e8c65ad43e31bafe62d1a1c980197491 Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Thu, 10 Mar 2022 06:01:50 -0500 Subject: [PATCH] wayland: Correctly handle xdg decoration configures Much like toplevel configures, xdg decoration configures only take effect once the xdg shell configure comes through. Also, let's get rid of some double computations because we unified the code paths. --- glfw/wl_platform.h | 2 ++ glfw/wl_window.c | 47 +++++++++++++++++++++++----------------------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/glfw/wl_platform.h b/glfw/wl_platform.h index 66f214428..1e31477db 100644 --- a/glfw/wl_platform.h +++ b/glfw/wl_platform.h @@ -129,6 +129,7 @@ static const WaylandWindowState TOPLEVEL_STATE_DOCKED = TOPLEVEL_STATE_MAXIMIZED enum WaylandWindowPendingState { PENDING_STATE_TOPLEVEL = 1, + PENDING_STATE_DECORATION = 2 }; // Wayland-specific per-window data @@ -224,6 +225,7 @@ typedef struct _GLFWwindowWayland struct { int width, height; uint32_t toplevel_states; + uint32_t decoration_mode; } current, pending; } _GLFWwindowWayland; diff --git a/glfw/wl_window.c b/glfw/wl_window.c index a7b80064b..5ee6ca7f7 100644 --- a/glfw/wl_window.c +++ b/glfw/wl_window.c @@ -269,24 +269,8 @@ xdgDecorationHandleConfigure(void* data, uint32_t mode) { _GLFWwindow* window = data; - - bool has_server_side_decorations = (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); - debug("XDG decoration configure event received: has_server_side_decorations: %d\n", has_server_side_decorations); - if (has_server_side_decorations == window->wl.decorations.serverSide) return; - window->wl.decorations.serverSide = has_server_side_decorations; - int width = window->wl.current.width, height = window->wl.current.height; - if (window->wl.decorations.serverSide) { - free_csd_surfaces(window); - height += window->wl.decorations.metrics.visible_titlebar_height; - } else { - ensure_csd_resources(window); - } - set_csd_window_geometry(window, &width, &height); - dispatchChangesAfterConfigure(window, width, height); - ensure_csd_resources(window); - wl_surface_commit(window->wl.surface); - debug("final window content size: %dx%d\n", window->wl.current.width, window->wl.current.height); - inform_compositor_of_window_geometry(window, "configure-decorations"); + window->wl.pending.decoration_mode = mode; + window->wl.pending_state |= PENDING_STATE_DECORATION; } static const struct zxdg_toplevel_decoration_v1_listener xdgDecorationListener = { @@ -511,17 +495,34 @@ static void xdgSurfaceHandleConfigure(void* data, bool live_resize_done = !(new_states & TOPLEVEL_STATE_RESIZING) && (window->wl.current.toplevel_states & TOPLEVEL_STATE_RESIZING); window->wl.current.toplevel_states = new_states; - set_csd_window_geometry(window, &width, &height); - dispatchChangesAfterConfigure(window, width, height); window->wl.current.width = width; window->wl.current.height = height; - debug("final window content size: %dx%d\n", window->wl.current.width, window->wl.current.height); _glfwInputWindowFocus(window, window->wl.current.toplevel_states & TOPLEVEL_STATE_ACTIVATED); - ensure_csd_resources(window); - inform_compositor_of_window_geometry(window, "configure"); if (live_resize_done) _glfwInputLiveResize(window, false); } } + + if (window->wl.pending_state & PENDING_STATE_DECORATION) { + uint32_t mode = window->wl.pending.decoration_mode; + bool has_server_side_decorations = (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); + debug("XDG decoration configure event received: has_server_side_decorations: %d\n", has_server_side_decorations); + window->wl.decorations.serverSide = has_server_side_decorations; + window->wl.current.decoration_mode = mode; + } + + if (window->wl.pending_state) { + int width = window->wl.pending.width, height = window->wl.pending.height; + set_csd_window_geometry(window, &width, &height); + dispatchChangesAfterConfigure(window, width, height); + if (window->wl.decorations.serverSide) { + free_csd_surfaces(window); + } else { + ensure_csd_resources(window); + } + debug("final window content size: %dx%d\n", width, height); + } + + inform_compositor_of_window_geometry(window, "configure"); wl_surface_commit(window->wl.surface); window->wl.pending_state = 0; }