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.
This commit is contained in:
Kovid Goyal 2021-04-07 15:08:44 +05:30
parent 593eb1d952
commit a19d1fc140
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 15 additions and 25 deletions

View File

@ -395,21 +395,15 @@ void
set_csd_window_geometry(_GLFWwindow *window, int32_t *width, int32_t *height) { 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 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; bool size_specified_by_compositor = *width > 0 && *height > 0;
if (size_specified_by_compositor) { if (!size_specified_by_compositor) {
if (has_csd) { *width = window->wl.user_requested_content_size.width;
*width += decs.metrics.width; *height += decs.metrics.width; *height = window->wl.user_requested_content_size.height;
} if (has_csd) *height += decs.metrics.visible_titlebar_height;
} else {
*width = window->wl.width; *height = window->wl.height;
} }
struct { int32_t x, y, width, height; } geometry = {.x = 0, .y = 0, .width = *width, .height = *height}; struct { int32_t x, y, width, height; } geometry = {.x = 0, .y = 0, .width = *width, .height = *height};
if (has_csd) { if (has_csd) {
int32_t visible_titlebar_height = decs.metrics.top - decs.metrics.width; geometry.y = -decs.metrics.visible_titlebar_height;
geometry.y = -visible_titlebar_height; *height -= decs.metrics.visible_titlebar_height;
*height -= decs.metrics.top;
*width -= decs.metrics.width;
geometry.width = *width;
geometry.height = *height + visible_titlebar_height;
} }
xdg_surface_set_window_geometry(window->wl.xdg.surface, geometry.x, geometry.y, geometry.width, geometry.height); xdg_surface_set_window_geometry(window->wl.xdg.surface, geometry.x, geometry.y, geometry.width, geometry.height);
} }

4
glfw/wl_platform.h vendored
View File

@ -183,7 +183,7 @@ typedef struct _GLFWwindowWayland
} for_window_state; } for_window_state;
struct { struct {
unsigned int width, top, horizontal, vertical; unsigned int width, top, horizontal, vertical, visible_titlebar_height;
} metrics; } metrics;
struct { struct {
@ -200,7 +200,7 @@ typedef struct _GLFWwindowWayland
struct { struct {
int32_t width, height; int32_t width, height;
} size_before_docking; } user_requested_content_size;
uint32_t toplevel_states; uint32_t toplevel_states;
bool maximize_on_first_show; bool maximize_on_first_show;

18
glfw/wl_window.c vendored
View File

@ -361,6 +361,8 @@ static bool createSurface(_GLFWwindow* window,
window->wl.width = wndconfig->width; window->wl.width = wndconfig->width;
window->wl.height = wndconfig->height; 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; window->wl.scale = 1;
if (!window->wl.transparent) if (!window->wl.transparent)
@ -423,18 +425,10 @@ static void xdgToplevelHandleConfigure(void* data,
} }
} }
if (report_event) printf("\n"); if (report_event) printf("\n");
if ((window->wl.toplevel_states & TOPLEVEL_STATE_DOCKED) && !(new_states & TOPLEVEL_STATE_DOCKED)) { if (new_states & TOPLEVEL_STATE_RESIZING) {
width = window->wl.size_before_docking.width; if (width) window->wl.user_requested_content_size.width = width;
height = window->wl.size_before_docking.height; if (height) window->wl.user_requested_content_size.height = 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 (width != 0 && height != 0) if (width != 0 && height != 0)
{ {
if (!(new_states & TOPLEVEL_STATE_DOCKED)) if (!(new_states & TOPLEVEL_STATE_DOCKED))
@ -452,6 +446,7 @@ static void xdgToplevelHandleConfigure(void* data,
} }
window->wl.toplevel_states = new_states; window->wl.toplevel_states = new_states;
set_csd_window_geometry(window, &width, &height); 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); wl_surface_commit(window->wl.surface);
dispatchChangesAfterConfigure(window, width, height); dispatchChangesAfterConfigure(window, width, height);
_glfwInputWindowFocus(window, window->wl.toplevel_states & TOPLEVEL_STATE_ACTIVATED); _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.width = 12;
window->wl.decorations.metrics.top = 36; 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.horizontal = 2 * window->wl.decorations.metrics.width;
window->wl.decorations.metrics.vertical = window->wl.decorations.metrics.width + window->wl.decorations.metrics.top; window->wl.decorations.metrics.vertical = window->wl.decorations.metrics.width + window->wl.decorations.metrics.top;
window->wl.transparent = fbconfig->transparent; window->wl.transparent = fbconfig->transparent;