summaryrefslogtreecommitdiffstats
path: root/usr.bin/tmux/tty.c
diff options
context:
space:
mode:
authornicm <nicm@openbsd.org>2009-10-12 17:19:47 +0000
committernicm <nicm@openbsd.org>2009-10-12 17:19:47 +0000
commit66869409e3203b973d4025e1e425b0d19913bf7d (patch)
treeea21cb0457e8a9d4184b8fafc604f37e5c45b07e /usr.bin/tmux/tty.c
parentWhen backspace is received at the beginning of a line and the previous line was (diff)
downloadwireguard-openbsd-66869409e3203b973d4025e1e425b0d19913bf7d.tar.xz
wireguard-openbsd-66869409e3203b973d4025e1e425b0d19913bf7d.zip
When drawing lines that have wrapped naturally, don't force a newline but
permit them to wrap naturally again. This allows terminals that use this to guess where lines start and end for eg mouse selecting (like xterm) to work correctly. This was another long-standing issue raised by several people over the last while. Thanks to martynas@ for much testing. This was not trivial to get right so bringing it in for wider testing and adn to fix any further glitches in-tree.
Diffstat (limited to 'usr.bin/tmux/tty.c')
-rw-r--r--usr.bin/tmux/tty.c53
1 files changed, 47 insertions, 6 deletions
diff --git a/usr.bin/tmux/tty.c b/usr.bin/tmux/tty.c
index 04484754705..21269c95df1 100644
--- a/usr.bin/tmux/tty.c
+++ b/usr.bin/tmux/tty.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tty.c,v 1.45 2009/10/12 16:41:02 nicm Exp $ */
+/* $OpenBSD: tty.c,v 1.46 2009/10/12 17:19:47 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -327,9 +327,10 @@ tty_putc(struct tty *tty, u_char ch)
if (tty->term->flags & TERM_EARLYWRAP)
sx--;
- if (tty->cx == sx) {
- tty->cx = 0;
- tty->cy++;
+ if (tty->cx >= sx) {
+ tty->cx = 1;
+ if (tty->cy != tty->rlower)
+ tty->cy++;
} else
tty->cx++;
}
@@ -440,6 +441,7 @@ void
tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
{
const struct grid_cell *gc;
+ struct grid_line *gl;
struct grid_cell tmpgc;
const struct grid_utf8 *gu;
u_int i, sx;
@@ -452,7 +454,17 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
if (sx > tty->sx)
sx = tty->sx;
- tty_cursor(tty, ox, oy + py);
+ /*
+ * Don't move the cursor to the start permission if it will wrap there
+ * itself; much the same as the conditions in tty_cmd_cell.
+ */
+ gl = NULL;
+ if (py != 0)
+ gl = &s->grid->linedata[s->grid->hsize + py - 1];
+ if (ox != 0 || (gl != NULL && !(gl->flags & GRID_LINE_WRAPPED)) ||
+ tty->cy != oy + py - 1 || tty->cx < tty->sx)
+ tty_cursor(tty, ox, oy + py);
+
for (i = 0; i < sx; i++) {
gc = grid_view_peek_cell(s->grid, i, py);
@@ -827,7 +839,36 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
{
- tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
+ struct window_pane *wp = ctx->wp;
+ struct screen *s = wp->screen;
+ struct grid_line *gl;
+ u_int wx, wy;
+
+ tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
+
+ wx = ctx->ocx + wp->xoff;
+ wy = ctx->ocy + wp->yoff;
+
+ /*
+ * If:
+ *
+ * - the line was wrapped:
+ * - the cursor is beyond the edge of the screen,
+ * - the desired position is at the left,
+ * - and either a) the desired next line is the one below the current
+ * or b) the current line is the bottom of the scroll region,
+ *
+ * Then just printing the next character will be enough to scroll into
+ * place, so don't do an explicit cursor move.
+ */
+ gl = NULL;
+ if (ctx->ocy != 0)
+ gl = &s->grid->linedata[s->grid->hsize + ctx->ocy - 1];
+ if (wy == 0 || (gl != NULL && !(gl->flags & GRID_LINE_WRAPPED)) ||
+ tty->cx < tty->sx || /* not at edge of screen */
+ wx != 0 || /* don't want 0 next */
+ (wy != tty->cy + 1 && tty->cy != ctx->orlower + wp->yoff))
+ tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
tty_cell(tty, ctx->cell, ctx->utf8);
}