Make full width panes try to play more nicely with terminal copy and
authornicm <nicm@openbsd.org>
Tue, 25 Apr 2017 18:30:29 +0000 (18:30 +0000)
committernicm <nicm@openbsd.org>
Tue, 25 Apr 2017 18:30:29 +0000 (18:30 +0000)
paste by avoiding explicit line wraps if we think the terminal will wrap
anyway.

usr.bin/tmux/screen-write.c
usr.bin/tmux/tmux.h
usr.bin/tmux/tty.c

index 0b89954..c1599c3 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: screen-write.c,v 1.117 2017/04/22 10:30:56 nicm Exp $ */
+/* $OpenBSD: screen-write.c,v 1.118 2017/04/25 18:30:29 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -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];
index f2c0625..74076d6 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.753 2017/04/25 18:20:51 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.754 2017/04/25 18:30:29 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1099,6 +1099,7 @@ struct tty_ctx {
        struct window_pane      *wp;
 
        const struct grid_cell  *cell;
+       int                      wrapped;
 
        u_int            num;
        void            *ptr;
index decb761..5551b0f 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tty.c,v 1.267 2017/04/23 18:13:24 nicm Exp $ */
+/* $OpenBSD: tty.c,v 1.268 2017/04/25 18:30:29 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -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 ||