diff --git a/render.c b/render.c index 2f79c6c1..d50606cb 100644 --- a/render.c +++ b/render.c @@ -3666,9 +3666,11 @@ tiocswinsz(struct terminal *term) static void delayed_reflow_of_normal_grid(struct terminal *term) { - if (term->render.resizing.grid == NULL) + if (term->interactive_resizing.grid == NULL) return; + xassert(term->interactive_resizing.new_rows > 0); + struct coord *const tracking_points[] = { &term->selection.coords.start, &term->selection.coords.end, @@ -3677,27 +3679,31 @@ delayed_reflow_of_normal_grid(struct terminal *term) /* Reflow the original (since before the resize was started) grid, * to the *current* dimensions */ grid_resize_and_reflow( - term->render.resizing.grid, - term->grid->num_rows, term->grid->num_cols, - term->render.resizing.screen_rows, term->rows, + term->interactive_resizing.grid, + term->interactive_resizing.new_rows, term->normal.num_cols, + term->interactive_resizing.old_screen_rows, term->rows, term->selection.coords.end.row >= 0 ? ALEN(tracking_points) : 0, tracking_points); /* Replace the current, truncated, “normal” grid with the * correctly reflowed one */ grid_free(&term->normal); - term->normal = *term->render.resizing.grid; - free(term->render.resizing.grid); + term->normal = *term->interactive_resizing.grid; + free(term->interactive_resizing.grid); /* Reset */ - term->render.resizing.grid = NULL; - term->render.resizing.screen_rows = 0; + term->interactive_resizing.grid = NULL; + term->interactive_resizing.old_screen_rows = 0; + term->interactive_resizing.new_rows = 0; /* Invalidate render pointers */ shm_unref(term->render.last_buf); term->render.last_buf = NULL; term->render.last_cursor.row = NULL; + tll_free(term->normal.scroll_damage); + sixel_reflow_grid(term, &term->normal); + if (term->grid == &term->normal) { term_damage_view(term); render_refresh(term); @@ -3895,8 +3901,6 @@ maybe_resize(struct terminal *term, int width, int height, bool force) const uint32_t scrollback_lines = term->render.scrollback_lines; /* - * Snapshot the “normal” grid. - * * Since text reflow is slow, don’t do it *while* resizing. Only * do it when done, or after “pausing” the resize for sufficiently * long. We re-use the TIOCSWINSZ timer to handle this. See @@ -3905,25 +3909,30 @@ maybe_resize(struct terminal *term, int width, int height, bool force) * To be able to do the final reflow correctly, we need a copy of * the original grid, before the resize started. */ - if (term->window->is_resizing && term->render.resizing.grid == NULL) { + if (term->window->is_resizing && term->interactive_resizing.grid == NULL) { + term_ptmx_pause(term); + /* Stash the current ‘normal’ grid, as-is, to be used when * doing the final reflow */ - term->render.resizing.screen_rows = term->rows; - term->render.resizing.grid = xmalloc(sizeof(*term->render.resizing.grid)); - *term->render.resizing.grid = term->normal; - + term->interactive_resizing.old_screen_rows = term->rows; + term->interactive_resizing.grid = xmalloc(sizeof(*term->interactive_resizing.grid)); + *term->interactive_resizing.grid = term->normal; /* * Copy the current viewport to a new grid that will be used * during the resize. For now, throw away sixels and OSC-8 * URLs. They’ll be "restored" when we do the final reflow. * + * We use the ‘alt’ screen’s row count, since we don’t want to + * instantiate an unnecessarily large grid. + * * TODO: * - sixels? * - OSC-8? */ + xassert(1 << (32 - __builtin_clz(term->rows)) == term->alt.num_rows); struct grid g = { - .num_rows = 1 << (32 - __builtin_clz(term->rows - 1)), + .num_rows = term->alt.num_rows, .num_cols = term->cols, .offset = 0, .view = 0, @@ -3945,7 +3954,6 @@ maybe_resize(struct terminal *term, int width, int height, bool force) } term->normal = g; - term_ptmx_pause(term); } /* Screen rows/cols before resize */ @@ -3985,9 +3993,10 @@ maybe_resize(struct terminal *term, int width, int height, bool force) xassert(term->margins.bottom >= pad_y); if (new_cols == old_cols && new_rows == old_rows && - (term->render.resizing.grid == NULL || term->window->is_resizing)) + (term->interactive_resizing.grid == NULL || term->window->is_resizing)) { LOG_DBG("grid layout unaffected; skipping reflow"); + term->interactive_resizing.new_rows = new_normal_grid_rows; goto damage_view; } @@ -4014,27 +4023,28 @@ maybe_resize(struct terminal *term, int width, int height, bool force) if (term->window->is_resizing) { /* Simple truncating resize, *while* an interactive resize is * ongoing. */ - xassert(term->render.resizing.grid != NULL); + xassert(term->interactive_resizing.grid != NULL); + xassert(new_normal_grid_rows > 0); + term->interactive_resizing.new_rows = new_normal_grid_rows; + grid_resize_without_reflow( - &term->normal, - new_normal_grid_rows, new_cols, - old_rows, - new_rows); + &term->normal, new_alt_grid_rows, new_cols, old_rows, new_rows); } else { /* Full text reflow */ - if (term->render.resizing.grid != NULL) { + if (term->interactive_resizing.grid != NULL) { /* Throw away the current, truncated, “normal” grid, and * use the original grid instead (from before the resize * started) */ grid_free(&term->normal); - term->normal = *term->render.resizing.grid; - free(term->render.resizing.grid); + term->normal = *term->interactive_resizing.grid; + free(term->interactive_resizing.grid); - old_rows = term->render.resizing.screen_rows; + old_rows = term->interactive_resizing.old_screen_rows; - term->render.resizing.grid = NULL; - term->render.resizing.screen_rows = 0; + term->interactive_resizing.grid = NULL; + term->interactive_resizing.old_screen_rows = 0; + term->interactive_resizing.new_rows = 0; term_ptmx_resume(term); } diff --git a/terminal.h b/terminal.h index 16c8e776..d5ed1ba2 100644 --- a/terminal.h +++ b/terminal.h @@ -595,14 +595,15 @@ struct terminal { size_t search_glyph_offset; - struct { - struct grid *grid; - int screen_rows; - } resizing; - struct timespec input_time; } render; + struct { + struct grid *grid; /* Original ‘normal’ grid, before resize started */ + int old_screen_rows; /* term->rows before resize started */ + int new_rows; /* New number of scrollback rows */ + } interactive_resizing; + struct { enum { SIXEL_DECSIXEL, /* DECSIXEL body part ", $, -, ? ... ~ */