grid: reflow: don’t line-wrap the last row

Before this patch, we would line-wrap the last row, just like any
other row, and then afterwards try to reverse this, by adjusting the
offset and free:ing and NULL:ing the "last row".

The problem with this is if the scrollback is full. In this case, the
row we’re freeing is the first row in the scrollback history. This
means we’ll crash as soon as the viewport is moved to the top of the
scrollback.

The fix is fairly, simple. Skip the post-processing logic, and instead
detect when we’re line-wrapping the last row, and skip the call to
line_wrap().

This way, the last row in the new grid corresponds to the last row in
the old grid.
This commit is contained in:
Daniel Eklöf 2022-08-29 20:47:33 +02:00
parent 13281f327b
commit 5c86358cd1
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F

24
grid.c
View file

@ -935,13 +935,14 @@ grid_resize_and_reflow(
start += cols;
}
if (old_row->linebreak) {
/* Erase the remaining cells */
memset(&new_row->cells[new_col_idx], 0,
(new_cols - new_col_idx) * sizeof(new_row->cells[0]));
new_row->linebreak = true;
line_wrap();
if (r + 1 < old_rows)
line_wrap();
}
grid_row_free(old_grid[old_row_idx]);
@ -985,25 +986,6 @@ grid_resize_and_reflow(
/* Set offset such that the last reflowed row is at the bottom */
grid->offset = new_row_idx - new_screen_rows + 1;
if (new_col_idx == 0) {
int next_to_last_new_row_idx = new_row_idx - 1;
next_to_last_new_row_idx += new_rows;
next_to_last_new_row_idx &= new_rows - 1;
const struct row *next_to_last_row = new_grid[next_to_last_new_row_idx];
if (next_to_last_row != NULL && next_to_last_row->linebreak) {
/*
* The next to last row is actually the *last* row. But we
* ended the reflow with a line-break, causing an empty
* row to be inserted at the bottom. Undo this.
*/
/* TODO: can we detect this in the reflow loop above instead? */
grid->offset--;
grid_row_free(new_grid[new_row_idx]);
new_grid[new_row_idx] = NULL;
}
}
while (grid->offset < 0)
grid->offset += new_rows;
while (new_grid[grid->offset] == NULL)