From 91d112bf12789da07e25ed001f7961b1d6bd7a76 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 18 Jan 2021 10:27:54 +0000 Subject: [PATCH] There is no need to clear every line entirely before drawing to it, this means moving the cursor and messes up wrapping. Better to just clear the sections that aren't written over. GitHub issue 2537. --- grid.c | 1 - screen-write.c | 32 +++++++++++++++++++++++++------- tmux.h | 1 - tty.c | 13 +------------ 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/grid.c b/grid.c index 96302fc3..cce304c9 100644 --- a/grid.c +++ b/grid.c @@ -698,7 +698,6 @@ grid_move_lines(struct grid *gd, u_int dy, u_int py, u_int ny, u_int bg) gd->linedata[py - 1].flags &= ~GRID_LINE_WRAPPED; } - /* Move a group of cells. */ void grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx, diff --git a/screen-write.c b/screen-write.c index 92f1aa39..7df5cd92 100644 --- a/screen-write.c +++ b/screen-write.c @@ -259,7 +259,6 @@ screen_write_start_callback(struct screen_write_ctx *ctx, struct screen *s, } } - /* Initialize writing. */ void screen_write_start(struct screen_write_ctx *ctx, struct screen *s) @@ -1517,6 +1516,7 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, struct screen_write_collect_item *ci, *tmp; struct screen_write_collect_line *cl; u_int y, cx, cy, items = 0; + int clear = 0; struct tty_ctx ttyctx; size_t written = 0; @@ -1540,22 +1540,29 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, cx = s->cx; cy = s->cy; for (y = 0; y < screen_size_y(s); y++) { cl = &ctx->s->write_list[y]; - if (cl->bg != 0) { - screen_write_set_cursor(ctx, 0, y); - screen_write_initctx(ctx, &ttyctx, 1); - ttyctx.bg = cl->bg - 1; - tty_write(tty_cmd_clearline, &ttyctx); - } TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) { + if (clear != -1 && + (u_int)clear != ci->x && + cl->bg != 0) { + screen_write_set_cursor(ctx, clear, y); + screen_write_initctx(ctx, &ttyctx, 1); + ttyctx.bg = cl->bg - 1; + ttyctx.num = ci->x - clear; + log_debug("clear %u at %u", ttyctx.num, clear); + tty_write(tty_cmd_clearcharacter, &ttyctx); + } + screen_write_set_cursor(ctx, ci->x, y); if (ci->type == CLEAR_END) { screen_write_initctx(ctx, &ttyctx, 1); ttyctx.bg = ci->bg; tty_write(tty_cmd_clearendofline, &ttyctx); + clear = -1; } else if (ci->type == CLEAR_START) { screen_write_initctx(ctx, &ttyctx, 1); ttyctx.bg = ci->bg; tty_write(tty_cmd_clearstartofline, &ttyctx); + clear = ci->x + 1; } else { screen_write_initctx(ctx, &ttyctx, 0); ttyctx.cell = &ci->gc; @@ -1563,6 +1570,7 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, ttyctx.ptr = cl->data + ci->x; ttyctx.num = ci->used; tty_write(tty_cmd_cells, &ttyctx); + clear = ci->x + ci->used; } items++; @@ -1571,6 +1579,16 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, TAILQ_REMOVE(&cl->items, ci, entry); free(ci); } + if (clear != -1 && + (u_int)clear != screen_size_x(s) - 1 && + cl->bg != 0) { + screen_write_set_cursor(ctx, clear, y); + screen_write_initctx(ctx, &ttyctx, 1); + ttyctx.bg = cl->bg - 1; + log_debug("clear to end at %u", clear); + tty_write(tty_cmd_clearendofline, &ttyctx); + } + clear = 0; cl->bg = 0; } s->cx = cx; s->cy = cy; diff --git a/tmux.h b/tmux.h index 832918e2..32f7fec7 100644 --- a/tmux.h +++ b/tmux.h @@ -1890,7 +1890,6 @@ const char *find_home(void); const char *getversion(void); void expand_paths(const char *, char ***, u_int *); - /* proc.c */ struct imsg; int proc_send(struct tmuxpeer *, enum msgtype, int, const void *, size_t); diff --git a/tty.c b/tty.c index fac7a99e..279bafaf 100644 --- a/tty.c +++ b/tty.c @@ -1531,20 +1531,9 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx) { - if (ctx->bigger) { - tty_draw_pane(tty, ctx, ctx->ocy); - return; - } - tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg); - tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); - - if (tty_term_has(tty->term, TTYC_ECH) && - !tty_fake_bce(tty, &ctx->defaults, 8)) - tty_putcode1(tty, TTYC_ECH, ctx->num); - else - tty_repeat_space(tty, ctx->num); + tty_clear_pane_line(tty, ctx, ctx->ocy, ctx->ocx, ctx->num, ctx->bg); } void