From ebd4a32768ba1e587fb884b58819605f4ef87c18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 20 Oct 2020 20:58:03 +0200 Subject: [PATCH] wayland: properly restore window size when being un-tiled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bind to xdg-shell version 2 if available, as this enables us to track our window’s ‘tiled’ state in the ‘configure’ events. This in turn allows us to stash the ‘old’ window size when being tiled, to be used again when restoring the window size when un-tiled. --- CHANGELOG.md | 1 + render.c | 17 +++++++++++------ terminal.h | 4 ++-- wayland.c | 38 +++++++++++++++++++++++++++++--------- wayland.h | 9 +++++++++ 5 files changed, 52 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b610573..31da15a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ * Crash when libxkbcommon cannot find a suitable libX11 _compose_ file. Note that foot will run, but without support for dead keys. (https://codeberg.org/dnkl/foot/issues/170). +* Restored window size when window is un-tiled. ## 1.5.2 diff --git a/render.c b/render.c index a5df70f7..819a249b 100644 --- a/render.c +++ b/render.c @@ -2038,9 +2038,9 @@ maybe_resize(struct terminal *term, int width, int height, bool force) * If we have a "last" used size - use that. Otherwise, use * the size from the user configuration. */ - if (term->unmaximized_width != 0 && term->unmaximized_height != 0) { - width = term->unmaximized_width; - height = term->unmaximized_height; + if (term->stashed_width != 0 && term->stashed_height != 0) { + width = term->stashed_width; + height = term->stashed_height; } else { switch (term->conf->size.type) { case CONF_SIZE_PX: @@ -2193,9 +2193,14 @@ maybe_resize(struct terminal *term, int width, int height, bool force) term->render.last_cursor.row = NULL; damage_view: - if (!term->window->is_maximized && !term->window->is_fullscreen) { - term->unmaximized_width = term->width; - term->unmaximized_height = term->height; + if (!term->window->is_maximized && + !term->window->is_fullscreen && + !term->window->is_tiled) + { + /* Stash current size, to enable us to restore it when we're + * being un-maximized/fullscreened/tiled */ + term->stashed_width = term->width; + term->stashed_height = term->height; } #if 0 diff --git a/terminal.h b/terminal.h index 2d199fcb..eede87c1 100644 --- a/terminal.h +++ b/terminal.h @@ -295,8 +295,8 @@ struct terminal { int scale; int width; /* pixels */ int height; /* pixels */ - int unmaximized_width; /* last unmaximized size, pixels */ - int unmaximized_height; /* last unmaximized size, pixels */ + int stashed_width; + int stashed_height; struct { int left; int right; diff --git a/wayland.c b/wayland.c index dce240d3..a663db4d 100644 --- a/wayland.c +++ b/wayland.c @@ -485,6 +485,10 @@ xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, bool is_activated = false; bool is_fullscreen = false; bool is_maximized = false; + bool is_tiled_top = false; + bool is_tiled_bottom = false; + bool is_tiled_left = false; + bool is_tiled_right = false; #if defined(LOG_ENABLE_DBG) && LOG_ENABLE_DBG char state_str[2048]; @@ -505,16 +509,17 @@ xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, enum xdg_toplevel_state *state; wl_array_for_each(state, states) { switch (*state) { - case XDG_TOPLEVEL_STATE_ACTIVATED: is_activated = true; break; - case XDG_TOPLEVEL_STATE_FULLSCREEN: is_fullscreen = true; break; - case XDG_TOPLEVEL_STATE_MAXIMIZED: is_maximized = true; break; + case XDG_TOPLEVEL_STATE_ACTIVATED: is_activated = true; break; + case XDG_TOPLEVEL_STATE_FULLSCREEN: is_fullscreen = true; break; + case XDG_TOPLEVEL_STATE_MAXIMIZED: is_maximized = true; break; + case XDG_TOPLEVEL_STATE_TILED_LEFT: is_tiled_left = true; break; + case XDG_TOPLEVEL_STATE_TILED_RIGHT: is_tiled_right = true; break; + case XDG_TOPLEVEL_STATE_TILED_TOP: is_tiled_top = true; break; + case XDG_TOPLEVEL_STATE_TILED_BOTTOM: is_tiled_bottom = true; break; case XDG_TOPLEVEL_STATE_RESIZING: - case XDG_TOPLEVEL_STATE_TILED_LEFT: - case XDG_TOPLEVEL_STATE_TILED_RIGHT: - case XDG_TOPLEVEL_STATE_TILED_TOP: - case XDG_TOPLEVEL_STATE_TILED_BOTTOM: /* Ignored */ + /* TODO: throttle? */ break; } @@ -535,7 +540,7 @@ xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, else state_str[0] = '\0'; - LOG_DBG("xdg-toplevel: configure: size=%dx%d, states=%s", + LOG_DBG("xdg-toplevel: configure: size=%dx%d, states=[%s]", width, height, state_str); #endif @@ -559,6 +564,10 @@ xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, win->configure.is_activated = is_activated; win->configure.is_fullscreen = is_fullscreen; win->configure.is_maximized = is_maximized; + win->configure.is_tiled_top = is_tiled_top; + win->configure.is_tiled_bottom = is_tiled_bottom; + win->configure.is_tiled_left = is_tiled_left; + win->configure.is_tiled_right = is_tiled_right; win->configure.width = width; win->configure.height = height; } @@ -589,6 +598,11 @@ xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, bool wasnt_configured = !win->is_configured; win->is_configured = true; win->is_maximized = win->configure.is_maximized; + win->is_tiled_top = win->configure.is_tiled_top; + win->is_tiled_bottom = win->configure.is_tiled_bottom; + win->is_tiled_left = win->configure.is_tiled_left; + win->is_tiled_right = win->configure.is_tiled_right; + win->is_tiled = win->is_tiled_top || win->is_tiled_bottom || win->is_tiled_left || win->is_tiled_right; if (win->is_fullscreen != win->configure.is_fullscreen && win->use_csd == CSD_YES) { if (win->configure.is_fullscreen) @@ -736,8 +750,14 @@ handle_global(void *data, struct wl_registry *registry, if (!verify_iface_version(interface, version, required)) return; + /* + * We *require* version 1, but _can_ use version 2. Version 2 + * adds 'tiled' window states. We use that information to + * restore the window size when window is un-tiled. + */ + wayl->shell = wl_registry_bind( - wayl->registry, name, &xdg_wm_base_interface, required); + wayl->registry, name, &xdg_wm_base_interface, min(version, 2)); xdg_wm_base_add_listener(wayl->shell, &xdg_wm_base_listener, wayl); } diff --git a/wayland.h b/wayland.h index 7d512ba0..70c2098a 100644 --- a/wayland.h +++ b/wayland.h @@ -314,10 +314,19 @@ struct wl_window { bool is_configured; bool is_fullscreen; bool is_maximized; + bool is_tiled_top; + bool is_tiled_bottom; + bool is_tiled_left; + bool is_tiled_right; + bool is_tiled; /* At least one of is_tiled_{top,bottom,left,right} is true */ struct { bool is_activated; bool is_fullscreen; bool is_maximized; + bool is_tiled_top; + bool is_tiled_bottom; + bool is_tiled_left; + bool is_tiled_right; int width; int height; } configure;