From a0d1d2f1c8c9a14125ff33c5bc46e8fc8ca62356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 24 Sep 2020 18:35:40 +0200 Subject: [PATCH 1/3] grid: reflow: retain scrollback position Closes #142 --- CHANGELOG.md | 2 ++ grid.c | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca17ca4a..a2b30c01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,8 @@ (https://codeberg.org/dnkl/foot/issues/146). * Color flashes when changing the color palette with OSC 4,10,11 (https://codeberg.org/dnkl/foot/issues/141). +* Scrollback position is now retained when resizing the window + (https://codeberg.org/dnkl/foot/issues/142). ### Security diff --git a/grid.c b/grid.c index e4b7c063..5f2b4277 100644 --- a/grid.c +++ b/grid.c @@ -65,6 +65,9 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols, const int old_rows = grid->num_rows; const int old_cols = grid->num_cols; + /* Is viewpoint tracking current grid offset? */ + const bool view_follows = grid->view == grid->offset; + int new_col_idx = 0; int new_row_idx = 0; @@ -97,9 +100,14 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols, tll_push_back(tracking_points, &cursor); tll_push_back(tracking_points, &saved_cursor); + struct coord viewport = {0, grid->view}; + if (!view_follows) + tll_push_back(tracking_points, &viewport); + for (size_t i = 0; i < tracking_points_count; i++) tll_push_back(tracking_points, _tracking_points[i]); + /* * Walk the old grid */ @@ -308,7 +316,8 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols, grid->offset += new_rows; while (new_grid[grid->offset] == NULL) grid->offset = (grid->offset + 1) & (new_rows - 1); - grid->view = grid->offset; + + grid->view = view_follows ? grid->offset : viewport.row; /* Ensure all visible rows have been allocated */ for (int r = 0; r < new_screen_rows; r++) { -- 2.30.2 From 8c183042874728848ec1b9d055f2b0cc020b9a28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 24 Sep 2020 18:48:41 +0200 Subject: [PATCH 2/3] grid: reflow: handle viewport being too far down when enlarging the window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the viewport is close to the bottom, but not *at* the bottom, and we’re enlarging the window, the translated viewport will be too far down. --- grid.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/grid.c b/grid.c index 5f2b4277..d8fc2842 100644 --- a/grid.c +++ b/grid.c @@ -317,8 +317,6 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols, while (new_grid[grid->offset] == NULL) grid->offset = (grid->offset + 1) & (new_rows - 1); - grid->view = view_follows ? grid->offset : viewport.row; - /* Ensure all visible rows have been allocated */ for (int r = 0; r < new_screen_rows; r++) { int idx = (grid->offset + r) & (new_rows - 1); @@ -326,6 +324,23 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols, new_grid[idx] = grid_row_alloc(new_cols, true); } + grid->view = view_follows ? grid->offset : viewport.row; + + /* If enlarging the window, the old viewport may be too far down, + * with unallocated rows. Make sure this cannot happen */ + while (true) { + int idx = (grid->view + new_screen_rows - 1) & (new_rows - 1); + if (new_grid[idx] != NULL) + break; + grid->view--; + if (grid->view < 0) + grid->view += new_rows; + } + for (size_t r = 0; r < new_screen_rows; r++) { + int idx = (grid->view + r) & (new_rows - 1); + assert(new_grid[idx] != NULL); + } + /* Free old grid */ for (int r = 0; r < grid->num_rows; r++) grid_row_free(old_grid[r]); -- 2.30.2 From 1718449ca652a64f091120f921cd7d91477f4f97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 24 Sep 2020 18:53:05 +0200 Subject: [PATCH 3/3] =?UTF-8?q?grid:=20reflow:=20fix=20release=20build;=20?= =?UTF-8?q?=E2=80=98idx=E2=80=99=20is=20only=20used=20in=20an=20assert()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- grid.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/grid.c b/grid.c index d8fc2842..a79b4493 100644 --- a/grid.c +++ b/grid.c @@ -6,6 +6,7 @@ #define LOG_MODULE "grid" #define LOG_ENABLE_DBG 0 #include "log.h" +#include "macros.h" #include "sixel.h" #include "util.h" #include "xmalloc.h" @@ -337,7 +338,7 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols, grid->view += new_rows; } for (size_t r = 0; r < new_screen_rows; r++) { - int idx = (grid->view + r) & (new_rows - 1); + int UNUSED idx = (grid->view + r) & (new_rows - 1); assert(new_grid[idx] != NULL); } -- 2.30.2