Make full width panes try to play more nicely with terminal copy and

paste by avoiding explicit line wraps if we think the terminal will wrap
anyway.
This commit is contained in:
nicm 2017-04-25 18:30:29 +00:00
parent 03d01eabb5
commit d520dae6ac
3 changed files with 35 additions and 17 deletions

View File

@ -41,6 +41,7 @@ static const struct grid_cell screen_write_pad_cell = {
struct screen_write_collect_item {
u_int x;
int wrapped;
u_int used;
char data[256];
@ -1054,6 +1055,7 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only)
screen_write_cursormove(ctx, ci->x, y);
screen_write_initctx(ctx, &ttyctx);
ttyctx.cell = &ci->gc;
ttyctx.wrapped = ci->wrapped;
ttyctx.ptr = ci->data;
ttyctx.num = ci->used;
tty_write(tty_cmd_cells, &ttyctx);
@ -1133,13 +1135,15 @@ screen_write_collect_add(struct screen_write_ctx *ctx,
if (s->cx > sx - 1 || ctx->item->used > sx - 1 - s->cx)
screen_write_collect_end(ctx);
ci = ctx->item; /* may have changed */
if (s->cx > sx - 1) {
log_debug("%s: wrapped at %u,%u", __func__, s->cx, s->cy);
ci->wrapped = 1;
screen_write_linefeed(ctx, 1);
s->cx = 0;
}
ci = ctx->item; /* may have changed */
if (ci->used == 0)
memcpy(&ci->gc, gc, sizeof ci->gc);
ci->data[ci->used++] = gc->data.data[0];

1
tmux.h
View File

@ -1099,6 +1099,7 @@ struct tty_ctx {
struct window_pane *wp;
const struct grid_cell *cell;
int wrapped;
u_int num;
void *ptr;

45
tty.c
View File

@ -540,9 +540,13 @@ void
tty_putn(struct tty *tty, const void *buf, size_t len, u_int width)
{
tty_add(tty, buf, len);
if (tty->cx + width > tty->sx)
tty->cx = tty->cy = UINT_MAX;
else
if (tty->cx + width > tty->sx) {
tty->cx = (tty->cx + width) - tty->sx;
if (tty->cx <= tty->sx)
tty->cy++;
else
tty->cx = tty->cy = UINT_MAX;
} else
tty->cx += width;
}
@ -773,18 +777,26 @@ tty_draw_line(struct tty *tty, const struct window_pane *wp,
if (sx > tty->sx)
sx = tty->sx;
if (screen_size_x(s) < tty->sx &&
ox == 0 &&
sx != screen_size_x(s) &&
tty_term_has(tty->term, TTYC_EL1) &&
!tty_fake_bce(tty, wp, 8)) {
tty_default_attributes(tty, wp, 8);
tty_cursor(tty, screen_size_x(s) - 1, oy + py);
tty_putcode(tty, TTYC_EL1);
cleared = 1;
}
if (sx != 0)
tty_cursor(tty, ox, oy + py);
if (wp == NULL ||
py == 0 ||
(~s->grid->linedata[s->grid->hsize + py - 1].flags & GRID_LINE_WRAPPED) ||
ox != 0 ||
tty->cx < tty->sx ||
screen_size_x(s) < tty->sx) {
if (screen_size_x(s) < tty->sx &&
ox == 0 &&
sx != screen_size_x(s) &&
tty_term_has(tty->term, TTYC_EL1) &&
!tty_fake_bce(tty, wp, 8)) {
tty_default_attributes(tty, wp, 8);
tty_cursor(tty, screen_size_x(s) - 1, oy + py);
tty_putcode(tty, TTYC_EL1);
cleared = 1;
}
if (sx != 0)
tty_cursor(tty, ox, oy + py);
} else
log_debug("%s: wrapped line %u", __func__, oy + py);
memcpy(&last, &grid_default_cell, sizeof last);
len = 0;
@ -1477,7 +1489,8 @@ static void
tty_cursor_pane_unless_wrap(struct tty *tty, const struct tty_ctx *ctx,
u_int cx, u_int cy)
{
if (!tty_pane_full_width(tty, ctx) ||
if (!ctx->wrapped ||
!tty_pane_full_width(tty, ctx) ||
(tty->term->flags & TERM_EARLYWRAP) ||
ctx->xoff + cx != 0 ||
ctx->yoff + cy != tty->cy + 1 ||