From 3e2b626107d7fcf55213399dab57f109c745e1b4 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 5 Apr 2021 09:10:47 +0530 Subject: [PATCH] Inform compositor of visible window geometry The numbers dont make logical sense, but they do what is expected on GNOME and since only GNOME is stupid enough to insist on CSD, that's all we care about. --- glfw/wl_client_side_decorations.c | 16 ++++++++++++++++ glfw/wl_client_side_decorations.h | 1 + glfw/wl_window.c | 10 ++-------- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/glfw/wl_client_side_decorations.c b/glfw/wl_client_side_decorations.c index 606088215d5..f3d34c35759 100644 --- a/glfw/wl_client_side_decorations.c +++ b/glfw/wl_client_side_decorations.c @@ -392,3 +392,19 @@ change_csd_title(_GLFWwindow *window) { damage_csd(top, decs.top.buffer.front); } } + +void +set_csd_window_geometry(_GLFWwindow *window, int32_t *width, int32_t *height) { + bool has_csd = window->decorated && !window->wl.decorations.serverSide && window->wl.decorations.left.surface && !window->wl.fullscreened; + bool size_specified_by_compositor = *width > 0 && *height > 0; + if (!size_specified_by_compositor) { *width = window->wl.width; *height = window->wl.height; } + struct { int32_t x, y, width, height; } geometry = {.x = 0, .y = 0, .width = *width, .height = *height}; + int scale = window->wl.scale >= 1 ? window->wl.scale : 1; + if (has_csd) { + int32_t visible_titlebar_height = decs.metrics.top - decs.metrics.width; + geometry.y = -decs.metrics.top + decs.metrics.width / scale; + geometry.height = *height; + *height -= visible_titlebar_height; + } + xdg_surface_set_window_geometry(window->wl.xdg.surface, geometry.x, geometry.y, geometry.width, geometry.height); +} diff --git a/glfw/wl_client_side_decorations.h b/glfw/wl_client_side_decorations.h index cb99e054331..c84b313d830 100644 --- a/glfw/wl_client_side_decorations.h +++ b/glfw/wl_client_side_decorations.h @@ -13,3 +13,4 @@ void free_csd_surfaces(_GLFWwindow *window); void resize_csd(_GLFWwindow *window); void change_csd_title(_GLFWwindow *window); bool ensure_csd_resources(_GLFWwindow *window); +void set_csd_window_geometry(_GLFWwindow *window, int32_t *width, int32_t *height); diff --git a/glfw/wl_window.c b/glfw/wl_window.c index f0b9884afaa..e0d2bd30eb2 100644 --- a/glfw/wl_window.c +++ b/glfw/wl_window.c @@ -237,8 +237,6 @@ clipboard_mime(void) { } static void dispatchChangesAfterConfigure(_GLFWwindow *window, int32_t width, int32_t height) { - if (width <= 0) width = window->wl.width; - if (height <= 0) height = window->wl.height; bool size_changed = width != window->wl.width || height != window->wl.height; bool scale_changed = checkScaleChange(window); @@ -444,12 +442,8 @@ static void xdgToplevelHandleConfigure(void* data, } } window->wl.fullscreened = fullscreen; - if (!fullscreen) { - if (window->decorated && !window->wl.decorations.serverSide && window->wl.decorations.left.surface) { - width -= window->wl.decorations.metrics.horizontal; - height -= window->wl.decorations.metrics.vertical; - } - } + set_csd_window_geometry(window, &width, &height); + wl_surface_commit(window->wl.surface); dispatchChangesAfterConfigure(window, width, height); _glfwInputWindowFocus(window, activated); ensure_csd_resources(window);