mirror of
https://github.com/tmux/tmux.git
synced 2024-12-13 10:08:47 +00:00
Sync OpenBSD patchset 401:
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.
This commit is contained in:
parent
cbd3b1bc9b
commit
6103628129
@ -1,4 +1,4 @@
|
|||||||
/* $Id: screen-write.c,v 1.76 2009-10-15 01:39:30 tcunha Exp $ */
|
/* $Id: screen-write.c,v 1.77 2009-10-15 01:41:14 tcunha Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -833,15 +833,15 @@ screen_write_mousemode(struct screen_write_ctx *ctx, int state)
|
|||||||
s->mode &= ~MODE_MOUSE;
|
s->mode &= ~MODE_MOUSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Line feed (down with scroll). */
|
/*
|
||||||
|
* Line feed the screen only (don't update the tty). Used for printing single
|
||||||
|
* characters, where might want to let the scroll happen naturally.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
screen_write_linefeed(struct screen_write_ctx *ctx, int wrapped)
|
screen_write_linefeedscreen(struct screen_write_ctx *ctx, int wrapped)
|
||||||
{
|
{
|
||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
struct grid_line *gl;
|
struct grid_line *gl;
|
||||||
struct tty_ctx ttyctx;
|
|
||||||
|
|
||||||
screen_write_initctx(ctx, &ttyctx);
|
|
||||||
|
|
||||||
gl = &s->grid->linedata[s->grid->hsize + s->cy];
|
gl = &s->grid->linedata[s->grid->hsize + s->cy];
|
||||||
if (wrapped)
|
if (wrapped)
|
||||||
@ -853,6 +853,17 @@ screen_write_linefeed(struct screen_write_ctx *ctx, int wrapped)
|
|||||||
grid_view_scroll_region_up(s->grid, s->rupper, s->rlower);
|
grid_view_scroll_region_up(s->grid, s->rupper, s->rlower);
|
||||||
else if (s->cy < screen_size_y(s) - 1)
|
else if (s->cy < screen_size_y(s) - 1)
|
||||||
s->cy++;
|
s->cy++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Line feed (down with scroll). */
|
||||||
|
void
|
||||||
|
screen_write_linefeed(struct screen_write_ctx *ctx, int wrapped)
|
||||||
|
{
|
||||||
|
struct tty_ctx ttyctx;
|
||||||
|
|
||||||
|
screen_write_initctx(ctx, &ttyctx);
|
||||||
|
|
||||||
|
screen_write_linefeedscreen(ctx, wrapped);
|
||||||
|
|
||||||
tty_write(tty_cmd_linefeed, &ttyctx);
|
tty_write(tty_cmd_linefeed, &ttyctx);
|
||||||
}
|
}
|
||||||
@ -952,6 +963,7 @@ screen_write_cell(
|
|||||||
struct screen_write_ctx *ctx, const struct grid_cell *gc, u_char *udata)
|
struct screen_write_ctx *ctx, const struct grid_cell *gc, u_char *udata)
|
||||||
{
|
{
|
||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
|
struct window_pane *wp = ctx->wp;
|
||||||
struct grid *gd = s->grid;
|
struct grid *gd = s->grid;
|
||||||
struct tty_ctx ttyctx;
|
struct tty_ctx ttyctx;
|
||||||
struct grid_utf8 gu, *tmp_gu;
|
struct grid_utf8 gu, *tmp_gu;
|
||||||
@ -1016,8 +1028,16 @@ screen_write_cell(
|
|||||||
|
|
||||||
/* Check this will fit on the current line and wrap if not. */
|
/* Check this will fit on the current line and wrap if not. */
|
||||||
if (s->cx > screen_size_x(s) - width) {
|
if (s->cx > screen_size_x(s) - width) {
|
||||||
screen_write_carriagereturn(ctx);
|
/*
|
||||||
|
* Don't update the terminal now, just update the screen and
|
||||||
|
* leave the cursor to scroll naturally, unless this is only
|
||||||
|
* part of the screen width.
|
||||||
|
*/
|
||||||
|
if (wp->xoff != 0 || wp->sx != screen_size_x(s))
|
||||||
screen_write_linefeed(ctx, 1);
|
screen_write_linefeed(ctx, 1);
|
||||||
|
else
|
||||||
|
screen_write_linefeedscreen(ctx, 1);
|
||||||
|
s->cx = 0; /* carriage return */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sanity checks. */
|
/* Sanity checks. */
|
||||||
|
3
tmux.h
3
tmux.h
@ -1,4 +1,4 @@
|
|||||||
/* $Id: tmux.h,v 1.474 2009-10-15 01:39:30 tcunha Exp $ */
|
/* $Id: tmux.h,v 1.475 2009-10-15 01:41:14 tcunha Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -1664,6 +1664,7 @@ void screen_write_scrollregion(struct screen_write_ctx *, u_int, u_int);
|
|||||||
void screen_write_insertmode(struct screen_write_ctx *, int);
|
void screen_write_insertmode(struct screen_write_ctx *, int);
|
||||||
void screen_write_mousemode(struct screen_write_ctx *, int);
|
void screen_write_mousemode(struct screen_write_ctx *, int);
|
||||||
void screen_write_linefeed(struct screen_write_ctx *, int);
|
void screen_write_linefeed(struct screen_write_ctx *, int);
|
||||||
|
void screen_write_linefeedscreen(struct screen_write_ctx *, int);
|
||||||
void screen_write_carriagereturn(struct screen_write_ctx *);
|
void screen_write_carriagereturn(struct screen_write_ctx *);
|
||||||
void screen_write_kcursormode(struct screen_write_ctx *, int);
|
void screen_write_kcursormode(struct screen_write_ctx *, int);
|
||||||
void screen_write_kkeypadmode(struct screen_write_ctx *, int);
|
void screen_write_kkeypadmode(struct screen_write_ctx *, int);
|
||||||
|
47
tty.c
47
tty.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: tty.c,v 1.149 2009-10-15 01:38:09 tcunha Exp $ */
|
/* $Id: tty.c,v 1.150 2009-10-15 01:41:14 tcunha Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -332,8 +332,9 @@ tty_putc(struct tty *tty, u_char ch)
|
|||||||
if (tty->term->flags & TERM_EARLYWRAP)
|
if (tty->term->flags & TERM_EARLYWRAP)
|
||||||
sx--;
|
sx--;
|
||||||
|
|
||||||
if (tty->cx == sx) {
|
if (tty->cx >= sx) {
|
||||||
tty->cx = 0;
|
tty->cx = 1;
|
||||||
|
if (tty->cy != tty->rlower)
|
||||||
tty->cy++;
|
tty->cy++;
|
||||||
} else
|
} else
|
||||||
tty->cx++;
|
tty->cx++;
|
||||||
@ -445,6 +446,7 @@ void
|
|||||||
tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
|
tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
|
||||||
{
|
{
|
||||||
const struct grid_cell *gc;
|
const struct grid_cell *gc;
|
||||||
|
struct grid_line *gl;
|
||||||
struct grid_cell tmpgc;
|
struct grid_cell tmpgc;
|
||||||
const struct grid_utf8 *gu;
|
const struct grid_utf8 *gu;
|
||||||
u_int i, sx;
|
u_int i, sx;
|
||||||
@ -457,7 +459,17 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
|
|||||||
if (sx > tty->sx)
|
if (sx > tty->sx)
|
||||||
sx = tty->sx;
|
sx = tty->sx;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
tty_cursor(tty, ox, oy + py);
|
||||||
|
|
||||||
for (i = 0; i < sx; i++) {
|
for (i = 0; i < sx; i++) {
|
||||||
gc = grid_view_peek_cell(s->grid, i, py);
|
gc = grid_view_peek_cell(s->grid, i, py);
|
||||||
|
|
||||||
@ -832,6 +844,35 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx)
|
|||||||
void
|
void
|
||||||
tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
|
tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
|
||||||
{
|
{
|
||||||
|
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_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
|
||||||
|
|
||||||
tty_cell(tty, ctx->cell, ctx->utf8);
|
tty_cell(tty, ctx->cell, ctx->utf8);
|
||||||
|
Loading…
Reference in New Issue
Block a user