diff --git a/grid.c b/grid.c index 2deb9111..4b9a7fb6 100644 --- a/grid.c +++ b/grid.c @@ -439,7 +439,7 @@ grid_row_alloc(int cols, bool initialize) { struct row *row = xmalloc(sizeof(*row)); row->dirty = false; - row->linebreak = false; + row->linebreak = true; row->extra = NULL; row->shell_integration.prompt_marker = false; row->shell_integration.cmd_start = -1; @@ -709,14 +709,21 @@ _line_wrap(struct grid *old_grid, struct row **new_grid, struct row *row, /* Scrollback not yet full, allocate a completely new row */ new_row = grid_row_alloc(col_count, false); new_grid[*row_idx] = new_row; + + /* *clear* linebreak, since we only want to set it when we + reach the end of an old row, with linebreak=true */ + new_row->linebreak = false; } else { /* Scrollback is full, need to reuse a row */ grid_row_reset_extra(new_row); - new_row->linebreak = false; new_row->shell_integration.prompt_marker = false; new_row->shell_integration.cmd_start = -1; new_row->shell_integration.cmd_end = -1; + /* *clear* linebreak, since we only want to set it when we + reach the end of an old row, with linebreak=true */ + new_row->linebreak = false; + tll_foreach(old_grid->sixel_images, it) { if (it->item.pos.row == *row_idx) { sixel_destroy(&it->item); @@ -894,6 +901,8 @@ grid_resize_and_reflow( i, tracking_points[i]->row, tracking_points[i]->col); } + int coalesced_linebreaks = 0; + /* * Walk the old grid */ @@ -984,6 +993,20 @@ grid_resize_and_reflow( } else underline_range = underline_range_terminator = NULL; + if (unlikely(col_count > 0 && coalesced_linebreaks > 0)) { + for (size_t apa = 0; apa < coalesced_linebreaks; apa++) { + /* 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; + + if (r + 1 < old_rows) + line_wrap(); + } + + coalesced_linebreaks = 0; + } + for (int c = 0; c < col_count;) { const struct cell *old = &old_row->cells[c]; @@ -1095,33 +1118,43 @@ grid_resize_and_reflow( } 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; - - if (r + 1 < old_rows) - line_wrap(); - else if (new_row->extra != NULL) { - if (new_row->extra->uri_ranges.count > 0) { - /* - * line_wrap() "closes" still-open URIs. Since - * this is the *last* row, and since we're - * line-breaking due to a hard line-break (rather - * than running out of cells in the "new_row"), - * there shouldn't be an open URI (it would have - * been closed when we reached the end of the URI - * while reflowing the last "old" row). - */ - int last_idx = new_row->extra->uri_ranges.count - 1; - xassert(new_row->extra->uri_ranges.v[last_idx].end >= 0); - } - - if (new_row->extra->underline_ranges.count > 0) { - int last_idx = new_row->extra->underline_ranges.count - 1; - xassert(new_row->extra->underline_ranges.v[last_idx].end >= 0); + if (col_count > 0) { + /* 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; + if (r + 1 < old_rows) { + /* Not the last (old) row */ + line_wrap(); + } else if (new_row->extra != NULL) { + if (new_row->extra->uri_ranges.count > 0) { + /* + * line_wrap() "closes" still-open URIs. Since + * this is the *last* row, and since we're + * line-breaking due to a hard line-break (rather + * than running out of cells in the "new_row"), + * there shouldn't be an open URI (it would have + * been closed when we reached the end of the URI + * while reflowing the last "old" row). + */ + int last_idx = new_row->extra->uri_ranges.count - 1; + xassert(new_row->extra->uri_ranges.v[last_idx].end >= 0); + } + + if (new_row->extra->underline_ranges.count > 0) { + int last_idx = new_row->extra->underline_ranges.count - 1; + xassert(new_row->extra->underline_ranges.v[last_idx].end >= 0); + } } + } else { + /* + * rows have linebreak=true by default. But we don't + * want trailing empty lines to result in actual lines + * in the new grid (think: empty window with prompt at + * the top) + */ + coalesced_linebreaks++; } } diff --git a/terminal.c b/terminal.c index 988716f4..2ba85276 100644 --- a/terminal.c +++ b/terminal.c @@ -2057,7 +2057,7 @@ static inline void erase_line(struct terminal *term, struct row *row) { erase_cell_range(term, row, 0, term->cols - 1); - row->linebreak = false; + row->linebreak = true; row->shell_integration.prompt_marker = false; row->shell_integration.cmd_start = -1; row->shell_integration.cmd_end = -1;