Merge branch 'dont-reflow-alt-screen'

Closes #221
This commit is contained in:
Daniel Eklöf 2020-11-25 20:33:56 +01:00
commit d151d4bc50
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
4 changed files with 140 additions and 20 deletions

View file

@ -92,6 +92,9 @@ means foot can be PGO:d in e.g. sandboxed build scripts. See
this.
* Sixel default maximum size is now 10000x10000 instead of the current
window size.
* Graphical glitches/flashes when resizing the window while running a
fullscreen application, i.e. the 'alt' screen
(https://codeberg.org/dnkl/foot/issues/221).
### Deprecated

131
grid.c
View file

@ -55,12 +55,125 @@ grid_row_free(struct row *row)
}
void
grid_reflow(struct grid *grid, int new_rows, int new_cols,
int old_screen_rows, int new_screen_rows,
size_t tracking_points_count,
struct coord *const _tracking_points[static tracking_points_count],
size_t compose_count, const struct
composed composed[static compose_count])
grid_resize_without_reflow(
struct grid *grid, int new_rows, int new_cols,
int old_screen_rows, int new_screen_rows)
{
struct row *const *old_grid = grid->rows;
const int old_rows = grid->num_rows;
const int old_cols = grid->num_cols;
struct row **new_grid = xcalloc(new_rows, sizeof(new_grid[0]));
tll(struct sixel) untranslated_sixels = tll_init();
tll_foreach(grid->sixel_images, it)
tll_push_back(untranslated_sixels, it->item);
tll_free(grid->sixel_images);
int new_offset = 0;
/* Copy old lines, truncating them if old rows were longer */
for (int r = 0, n = min(old_screen_rows, new_screen_rows); r < n; r++) {
const int old_row_idx = (grid->offset + r) & (old_rows - 1);
const int new_row_idx = (new_offset + r) & (new_rows - 1);
const struct row *old_row = old_grid[old_row_idx];
assert(old_row != NULL);
struct row *new_row = grid_row_alloc(new_cols, false);
new_grid[new_row_idx] = new_row;
memcpy(new_row->cells,
old_row->cells,
sizeof(struct cell) * min(old_cols, new_cols));
new_row->dirty = old_row->dirty;
new_row->linebreak = false;
/* Clear "new" columns */
if (new_cols > old_cols) {
memset(&new_row->cells[old_cols], 0,
sizeof(struct cell) * (new_cols - old_cols));
new_row->dirty = true;
}
/* Map sixels on current "old" row to current "new row" */
tll_foreach(untranslated_sixels, it) {
if (it->item.pos.row != old_row_idx)
continue;
struct sixel sixel = it->item;
sixel.pos.row = new_row_idx;
if (sixel.pos.col < new_cols)
tll_push_back(grid->sixel_images, sixel);
else
sixel_destroy(&it->item);
tll_remove(untranslated_sixels, it);
}
}
/* Clear "new" lines */
for (int r = min(old_screen_rows, new_screen_rows); r < new_screen_rows; r++) {
struct row *new_row = grid_row_alloc(new_cols, false);
new_grid[(new_offset + r) & (new_rows - 1)] = new_row;
memset(new_row->cells, 0, sizeof(struct cell) * new_cols);
new_row->linebreak = false;
new_row->dirty = true;
}
/* Free old grid */
for (int r = 0; r < grid->num_rows; r++)
grid_row_free(old_grid[r]);
free(grid->rows);
grid->rows = new_grid;
grid->num_rows = new_rows;
grid->num_cols = new_cols;
grid->view = grid->offset = new_offset;
/* Keep cursor at current position, but clamp to new dimensions */
struct coord cursor = grid->cursor.point;
if (cursor.row == old_screen_rows - 1) {
/* 'less' breaks if the cursor isn't at the bottom */
cursor.row = new_screen_rows - 1;
}
cursor.row = min(cursor.row, new_screen_rows - 1);
cursor.col = min(cursor.col, new_cols - 1);
grid->cursor.point = cursor;
struct coord saved_cursor = grid->saved_cursor.point;
if (saved_cursor.row == old_screen_rows - 1)
saved_cursor.row = new_screen_rows - 1;
saved_cursor.row = min(saved_cursor.row, new_screen_rows - 1);
saved_cursor.col = min(saved_cursor.col, new_cols - 1);
grid->saved_cursor.point = saved_cursor;
grid->cur_row = new_grid[(grid->offset + cursor.row) & (new_rows - 1)];
grid->cursor.lcf = false;
grid->saved_cursor.lcf = false;
/* Free sixels we failed to "map" to the new grid */
tll_foreach(untranslated_sixels, it)
sixel_destroy(&it->item);
tll_free(untranslated_sixels);
#if defined(_DEBUG)
for (int r = 0; r < new_screen_rows; r++)
grid_row_in_view(grid, r);
#endif
}
void
grid_resize_and_reflow(
struct grid *grid, int new_rows, int new_cols,
int old_screen_rows, int new_screen_rows,
size_t tracking_points_count,
struct coord *const _tracking_points[static tracking_points_count],
size_t compose_count, const struct
composed composed[static compose_count])
{
struct row *const *old_grid = grid->rows;
const int old_rows = grid->num_rows;
@ -305,7 +418,6 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols,
grid_row_free(old_grid[r]);
free(grid->rows);
grid->cur_row = new_grid[cursor.row];
grid->rows = new_grid;
grid->num_rows = new_rows;
grid->num_cols = new_cols;
@ -315,14 +427,15 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols,
while (cursor.row < 0)
cursor.row += grid->num_rows;
cursor.row = min(cursor.row, new_screen_rows - 1);
assert(cursor.col >= 0 && cursor.col < new_cols);
cursor.col = min(cursor.col, new_cols - 1);
saved_cursor.row -= grid->offset;
while (saved_cursor.row < 0)
saved_cursor.row += grid->num_rows;
saved_cursor.row = min(saved_cursor.row, new_screen_rows - 1);
assert(saved_cursor.col >= 0 && saved_cursor.col < new_cols);
saved_cursor.col = min(saved_cursor.col, new_cols - 1);
grid->cur_row = new_grid[(grid->offset + cursor.row) & (new_rows - 1)];
grid->cursor.point = cursor;
grid->saved_cursor.point = saved_cursor;

9
grid.h
View file

@ -6,11 +6,16 @@
void grid_swap_row(struct grid *grid, int row_a, int row_b);
struct row *grid_row_alloc(int cols, bool initialize);
void grid_row_free(struct row *row);
void grid_reflow(
void grid_resize_without_reflow(
struct grid *grid, int new_rows, int new_cols,
int old_screen_rows, int new_screen_rows);
void grid_resize_and_reflow(
struct grid *grid, int new_rows, int new_cols,
int old_screen_rows, int new_screen_rows,
size_t tracking_points_count,
struct coord *const tracking_points[static tracking_points_count],
struct coord *const _tracking_points[static tracking_points_count],
size_t compose_count,
const struct composed composed[static compose_count]);

View file

@ -2276,23 +2276,22 @@ maybe_resize(struct terminal *term, int width, int height, bool force)
goto damage_view;
}
if (term->grid == &term->alt)
selection_cancel(term);
struct coord *const tracking_points[] = {
&term->selection.start,
&term->selection.end,
};
/* Reflow grids */
grid_reflow(
/* Resize grids */
grid_resize_and_reflow(
&term->normal, new_normal_grid_rows, new_cols, old_rows, new_rows,
term->grid == &term->normal ? ALEN(tracking_points) : 0,
term->grid == &term->normal ? tracking_points : NULL,
ALEN(tracking_points), tracking_points,
term->composed_count, term->composed);
grid_reflow(
&term->alt, new_alt_grid_rows, new_cols, old_rows, new_rows,
term->grid == &term->alt ? ALEN(tracking_points) : 0,
term->grid == &term->alt ? tracking_points : NULL,
term->composed_count, term->composed);
grid_resize_without_reflow(
&term->alt, new_alt_grid_rows, new_cols, old_rows, new_rows);
/* Reset tab stops */
tll_free(term->tab_stops);