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 606088215..f3d34c357 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 cb99e0543..c84b313d8 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 f0b9884af..e0d2bd30e 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);