mirror of
https://github.com/tmux/tmux.git
synced 2026-05-31 14:46:17 +00:00
Redraw line directly for wide cells in screen_write_cell, fix up selection and
generally tidy.
This commit is contained in:
@@ -629,25 +629,25 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src,
|
|||||||
|
|
||||||
if (nx == 0 || ny == 0)
|
if (nx == 0 || ny == 0)
|
||||||
return;
|
return;
|
||||||
|
if (wp != NULL)
|
||||||
|
yoff = wp->yoff;
|
||||||
|
|
||||||
for (yy = py; yy < py + ny; yy++) {
|
for (yy = py; yy < py + ny; yy++) {
|
||||||
if (yy >= gd->hsize + gd->sy)
|
if (yy >= gd->hsize + gd->sy)
|
||||||
break;
|
break;
|
||||||
s->cx = cx;
|
s->cx = cx;
|
||||||
screen_write_initctx(ctx, &ttyctx, 0, 0);
|
screen_write_initctx(ctx, &ttyctx, 0, 0);
|
||||||
if (wp != NULL)
|
|
||||||
yoff = wp->yoff;
|
|
||||||
r = screen_redraw_get_visible_ranges(wp, px, s->cy + yoff, nx,
|
r = screen_redraw_get_visible_ranges(wp, px, s->cy + yoff, nx,
|
||||||
NULL);
|
NULL);
|
||||||
for (xx = px; xx < px + nx; xx++) {
|
for (xx = px; xx < px + nx; xx++) {
|
||||||
gl = grid_get_line(gd, yy);
|
gl = grid_get_line(gd, yy);
|
||||||
sgl = grid_get_line(ctx->s->grid, s->cy);
|
sgl = grid_get_line(s->grid, s->cy);
|
||||||
if (xx >= gl->cellsize && s->cx >= sgl->cellsize)
|
if (xx >= gl->cellsize && s->cx >= sgl->cellsize)
|
||||||
break;
|
break;
|
||||||
grid_get_cell(gd, xx, yy, &gc);
|
grid_get_cell(gd, xx, yy, &gc);
|
||||||
if (xx + gc.data.width > px + nx)
|
if (xx + gc.data.width > px + nx)
|
||||||
break;
|
break;
|
||||||
grid_view_set_cell(ctx->s->grid, s->cx, s->cy, &gc);
|
grid_view_set_cell(s->grid, s->cx, s->cy, &gc);
|
||||||
if (!screen_redraw_is_visible(r, px))
|
if (!screen_redraw_is_visible(r, px))
|
||||||
break;
|
break;
|
||||||
ttyctx.cell = &gc;
|
ttyctx.cell = &gc;
|
||||||
@@ -1124,7 +1124,7 @@ screen_write_redraw_line(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx,
|
|||||||
{
|
{
|
||||||
struct window_pane *wp = ctx->wp;
|
struct window_pane *wp = ctx->wp;
|
||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
struct grid_cell gc;
|
struct grid_cell gc, ngc;
|
||||||
u_int sx = screen_size_x(s), cx, i, n;
|
u_int sx = screen_size_x(s), cx, i, n;
|
||||||
u_int xoff = wp->xoff, yoff = wp->yoff;
|
u_int xoff = wp->xoff, yoff = wp->yoff;
|
||||||
struct visible_ranges *r;
|
struct visible_ranges *r;
|
||||||
@@ -1139,9 +1139,15 @@ screen_write_redraw_line(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx,
|
|||||||
cx = ri->px - xoff;
|
cx = ri->px - xoff;
|
||||||
for (n = 0; n < ri->nx && cx < sx; n++, cx++) {
|
for (n = 0; n < ri->nx && cx < sx; n++, cx++) {
|
||||||
grid_view_get_cell(s->grid, cx, yy, &gc);
|
grid_view_get_cell(s->grid, cx, yy, &gc);
|
||||||
|
if (~gc.flags & GRID_FLAG_SELECTED)
|
||||||
|
ttyctx->cell = &gc;
|
||||||
|
else {
|
||||||
|
screen_select_cell(s, &ngc, &gc);
|
||||||
|
ttyctx->cell = &ngc;
|
||||||
|
}
|
||||||
|
|
||||||
ttyctx->ocx = cx;
|
ttyctx->ocx = cx;
|
||||||
ttyctx->ocy = yy;
|
ttyctx->ocy = yy;
|
||||||
ttyctx->cell = &gc;
|
|
||||||
tty_write(tty_cmd_cell, ttyctx);
|
tty_write(tty_cmd_cell, ttyctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2169,7 +2175,8 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
|
|||||||
written = 0;
|
written = 0;
|
||||||
for (i = 0; i < r->used; i++) {
|
for (i = 0; i < r->used; i++) {
|
||||||
ri = &r->ranges[i];
|
ri = &r->ranges[i];
|
||||||
if (ri->nx == 0) continue;
|
if (ri->nx == 0)
|
||||||
|
continue;
|
||||||
r_start = ri->px;
|
r_start = ri->px;
|
||||||
r_end = ri->px + ri->nx;
|
r_end = ri->px + ri->nx;
|
||||||
ci_start = ci->x;
|
ci_start = ci->x;
|
||||||
@@ -2521,6 +2528,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
|||||||
if (selected)
|
if (selected)
|
||||||
skip = 0;
|
skip = 0;
|
||||||
|
|
||||||
|
/* Get visible ranges for the character before moving the cursor. */
|
||||||
if (wp != NULL)
|
if (wp != NULL)
|
||||||
yoff = wp->yoff;
|
yoff = wp->yoff;
|
||||||
r = screen_redraw_get_visible_ranges(wp, s->cx, s->cy + yoff, width,
|
r = screen_redraw_get_visible_ranges(wp, s->cx, s->cy + yoff, width,
|
||||||
@@ -2534,7 +2542,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
|||||||
if (s->cx <= sx - not_wrap - width)
|
if (s->cx <= sx - not_wrap - width)
|
||||||
screen_write_set_cursor(ctx, s->cx + width, -1);
|
screen_write_set_cursor(ctx, s->cx + width, -1);
|
||||||
else
|
else
|
||||||
screen_write_set_cursor(ctx, sx - not_wrap, -1);
|
screen_write_set_cursor(ctx, sx - not_wrap, -1);
|
||||||
|
|
||||||
/* Create space for character in insert mode. */
|
/* Create space for character in insert mode. */
|
||||||
if (s->mode & MODE_INSERT) {
|
if (s->mode & MODE_INSERT) {
|
||||||
@@ -2543,33 +2551,42 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
|||||||
tty_write(tty_cmd_insertcharacter, &ttyctx);
|
tty_write(tty_cmd_insertcharacter, &ttyctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write to the screen. */
|
/* If not writing, done now. */
|
||||||
if (!skip && !(s->mode & MODE_SYNC)) {
|
if (skip || s->mode & MODE_SYNC)
|
||||||
if (selected) {
|
return;
|
||||||
screen_select_cell(s, &tmp_gc, gc);
|
|
||||||
} else
|
/* Do a full line redraw if needed. */
|
||||||
memcpy(&tmp_gc, gc, sizeof tmp_gc);
|
if (redraw) {
|
||||||
ttyctx.cell = &tmp_gc;
|
screen_write_redraw_line(ctx, &ttyctx, s->cy);
|
||||||
if (redraw)
|
return;
|
||||||
ttyctx.flags |= TTY_CTX_CELL_DRAW_LINE;
|
}
|
||||||
for (i=0, vis=0; i < r->used; i++) vis += r->ranges[i].nx;
|
|
||||||
if (vis < width) {
|
/* Work out the cell attributes. */
|
||||||
/* Wide character or tab partly obscured. Write
|
if (selected)
|
||||||
* spaces one by one in unobscured region(s).
|
screen_select_cell(s, &tmp_gc, gc);
|
||||||
*/
|
else
|
||||||
*tmp_gc.data.data = ' ';
|
memcpy(&tmp_gc, gc, sizeof tmp_gc);
|
||||||
tmp_gc.data.width = tmp_gc.data.size =
|
ttyctx.cell = &tmp_gc;
|
||||||
tmp_gc.data.have = 1;
|
|
||||||
for (i=0; i < r->used; i++) {
|
/* If the cell is fully visible, it can be written entirely. */
|
||||||
ri = &r->ranges[i];
|
for (i = 0, vis = 0; i < r->used; i++)
|
||||||
if (ri->nx == 0) continue;
|
vis += r->ranges[i].nx;
|
||||||
for (n = 0; n < ri->nx; n++) {
|
if (vis >= width) {
|
||||||
screen_write_set_cursor(ctx, ri->px + n,
|
tty_write(tty_cmd_cell, &ttyctx);
|
||||||
-1);
|
return;
|
||||||
tty_write(tty_cmd_cell, &ttyctx);
|
}
|
||||||
}
|
|
||||||
}
|
/*
|
||||||
} else {
|
* Otherwise this is a wide character or tab partly obscured. Write
|
||||||
|
* spaces in the visible regions.
|
||||||
|
*/
|
||||||
|
utf8_set(&tmp_gc.data, ' ');
|
||||||
|
for (i = 0; i < r->used; i++) {
|
||||||
|
ri = &r->ranges[i];
|
||||||
|
if (ri->nx == 0)
|
||||||
|
continue;
|
||||||
|
for (n = 0; n < ri->nx; n++) {
|
||||||
|
ttyctx.ocx = ri->px + n;
|
||||||
tty_write(tty_cmd_cell, &ttyctx);
|
tty_write(tty_cmd_cell, &ttyctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2583,6 +2600,7 @@ screen_write_combine(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
|||||||
struct window_pane *wp = ctx->wp;
|
struct window_pane *wp = ctx->wp;
|
||||||
struct grid *gd = s->grid;
|
struct grid *gd = s->grid;
|
||||||
const struct utf8_data *ud = &gc->data;
|
const struct utf8_data *ud = &gc->data;
|
||||||
|
struct options *oo = global_options;
|
||||||
u_int i, n, cx = s->cx, cy = s->cy, vis, yoff = 0;
|
u_int i, n, cx = s->cx, cy = s->cy, vis, yoff = 0;
|
||||||
struct grid_cell last;
|
struct grid_cell last;
|
||||||
struct tty_ctx ttyctx;
|
struct tty_ctx ttyctx;
|
||||||
@@ -2602,7 +2620,7 @@ screen_write_combine(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
|||||||
zero_width = 1;
|
zero_width = 1;
|
||||||
else if (utf8_is_vs(ud)) {
|
else if (utf8_is_vs(ud)) {
|
||||||
zero_width = 1;
|
zero_width = 1;
|
||||||
if (options_get_number(global_options, "variation-selector-always-wide"))
|
if (options_get_number(oo, "variation-selector-always-wide"))
|
||||||
force_wide = 1;
|
force_wide = 1;
|
||||||
} else if (ud->width == 0)
|
} else if (ud->width == 0)
|
||||||
zero_width = 1;
|
zero_width = 1;
|
||||||
|
|||||||
5
tmux.h
5
tmux.h
@@ -1742,9 +1742,8 @@ struct tty_ctx {
|
|||||||
#define TTY_CTX_WINDOW_BIGGER 0x4
|
#define TTY_CTX_WINDOW_BIGGER 0x4
|
||||||
#define TTY_CTX_SYNC 0x8
|
#define TTY_CTX_SYNC 0x8
|
||||||
#define TTY_CTX_OVERLAY_SYNC 0x10
|
#define TTY_CTX_OVERLAY_SYNC 0x10
|
||||||
#define TTY_CTX_CELL_DRAW_LINE 0x20
|
#define TTY_CTX_CELL_INVALIDATE 0x20
|
||||||
#define TTY_CTX_CELL_INVALIDATE 0x40
|
#define TTY_CTX_PANE_OBSCURED 0x40
|
||||||
#define TTY_CTX_PANE_OBSCURED 0x80
|
|
||||||
|
|
||||||
union {
|
union {
|
||||||
u_int n;
|
u_int n;
|
||||||
|
|||||||
9
tty.c
9
tty.c
@@ -2054,14 +2054,7 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
|
|||||||
(gcp->data.width == 1 && !tty_check_overlay(tty, px, py)))
|
(gcp->data.width == 1 && !tty_check_overlay(tty, px, py)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ctx->flags & TTY_CTX_CELL_DRAW_LINE) {
|
if (gcp->data.width > 1) { /* could be partially obscured */
|
||||||
tty_draw_line(tty, s, 0, s->cy, screen_size_x(s),
|
|
||||||
ctx->xoff - ctx->wox, py, &ctx->defaults, ctx->palette);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle partially obstructed wide characters. */
|
|
||||||
if (gcp->data.width > 1) {
|
|
||||||
r = tty_check_overlay_range(tty, px, py, gcp->data.width);
|
r = tty_check_overlay_range(tty, px, py, gcp->data.width);
|
||||||
for (i = 0; i < r->used; i++)
|
for (i = 0; i < r->used; i++)
|
||||||
vis += r->ranges[i].nx;
|
vis += r->ranges[i].nx;
|
||||||
|
|||||||
Reference in New Issue
Block a user