From a19d1fc140f4016cc047c4ce41f7f6ab3723b597 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 7 Apr 2021 15:08:44 +0530 Subject: [PATCH] Restore size after all types of docking not just maximize/unmaximize We make use of the fact that wayland tells us when the window is being resized to track actual user requested sizes as opposed to compositor requested ones. --- glfw/wl_client_side_decorations.c | 18 ++++++------------ glfw/wl_platform.h | 4 ++-- glfw/wl_window.c | 18 +++++++----------- 3 files changed, 15 insertions(+), 25 deletions(-) diff --git a/glfw/wl_client_side_decorations.c b/glfw/wl_client_side_decorations.c index 6e13a07e9..891cf75d6 100644 --- a/glfw/wl_client_side_decorations.c +++ b/glfw/wl_client_side_decorations.c @@ -395,21 +395,15 @@ 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.toplevel_states & TOPLEVEL_STATE_FULLSCREEN); bool size_specified_by_compositor = *width > 0 && *height > 0; - if (size_specified_by_compositor) { - if (has_csd) { - *width += decs.metrics.width; *height += decs.metrics.width; - } - } else { - *width = window->wl.width; *height = window->wl.height; + if (!size_specified_by_compositor) { + *width = window->wl.user_requested_content_size.width; + *height = window->wl.user_requested_content_size.height; + if (has_csd) *height += decs.metrics.visible_titlebar_height; } struct { int32_t x, y, width, height; } geometry = {.x = 0, .y = 0, .width = *width, .height = *height}; if (has_csd) { - int32_t visible_titlebar_height = decs.metrics.top - decs.metrics.width; - geometry.y = -visible_titlebar_height; - *height -= decs.metrics.top; - *width -= decs.metrics.width; - geometry.width = *width; - geometry.height = *height + visible_titlebar_height; + geometry.y = -decs.metrics.visible_titlebar_height; + *height -= decs.metrics.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_platform.h b/glfw/wl_platform.h index 06444d13f..345deb243 100644 --- a/glfw/wl_platform.h +++ b/glfw/wl_platform.h @@ -183,7 +183,7 @@ typedef struct _GLFWwindowWayland } for_window_state; struct { - unsigned int width, top, horizontal, vertical; + unsigned int width, top, horizontal, vertical, visible_titlebar_height; } metrics; struct { @@ -200,7 +200,7 @@ typedef struct _GLFWwindowWayland struct { int32_t width, height; - } size_before_docking; + } user_requested_content_size; uint32_t toplevel_states; bool maximize_on_first_show; diff --git a/glfw/wl_window.c b/glfw/wl_window.c index 7d70aba53..6bf3bf41e 100644 --- a/glfw/wl_window.c +++ b/glfw/wl_window.c @@ -361,6 +361,8 @@ static bool createSurface(_GLFWwindow* window, window->wl.width = wndconfig->width; window->wl.height = wndconfig->height; + window->wl.user_requested_content_size.width = wndconfig->width; + window->wl.user_requested_content_size.height = wndconfig->height; window->wl.scale = 1; if (!window->wl.transparent) @@ -423,18 +425,10 @@ static void xdgToplevelHandleConfigure(void* data, } } if (report_event) printf("\n"); - if ((window->wl.toplevel_states & TOPLEVEL_STATE_DOCKED) && !(new_states & TOPLEVEL_STATE_DOCKED)) { - width = window->wl.size_before_docking.width; - height = window->wl.size_before_docking.height; - window->wl.size_before_docking.width = 0; - window->wl.size_before_docking.height = 0; - if (report_event) printf("Restoring size on undock to: %dx%d\n", width, height); - } else if (!(window->wl.toplevel_states & TOPLEVEL_STATE_DOCKED) && (new_states & TOPLEVEL_STATE_DOCKED)) { - window->wl.size_before_docking.width = window->wl.width; - window->wl.size_before_docking.height = window->wl.height; - if (report_event) printf("Saving size on undock to: %dx%d\n", window->wl.width, window->wl.height); + if (new_states & TOPLEVEL_STATE_RESIZING) { + if (width) window->wl.user_requested_content_size.width = width; + if (height) window->wl.user_requested_content_size.height = height; } - if (width != 0 && height != 0) { if (!(new_states & TOPLEVEL_STATE_DOCKED)) @@ -452,6 +446,7 @@ static void xdgToplevelHandleConfigure(void* data, } window->wl.toplevel_states = new_states; set_csd_window_geometry(window, &width, &height); + if (report_event) printf("final window size: %dx%d\n", window->wl.width, window->wl.height); wl_surface_commit(window->wl.surface); dispatchChangesAfterConfigure(window, width, height); _glfwInputWindowFocus(window, window->wl.toplevel_states & TOPLEVEL_STATE_ACTIVATED); @@ -713,6 +708,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, { window->wl.decorations.metrics.width = 12; window->wl.decorations.metrics.top = 36; + window->wl.decorations.metrics.visible_titlebar_height = window->wl.decorations.metrics.top - window->wl.decorations.metrics.width; window->wl.decorations.metrics.horizontal = 2 * window->wl.decorations.metrics.width; window->wl.decorations.metrics.vertical = window->wl.decorations.metrics.width + window->wl.decorations.metrics.top; window->wl.transparent = fbconfig->transparent;