mirror of
https://github.com/tmux/tmux.git
synced 2025-01-07 16:28:48 +00:00
Add support for the iTerm2 sychronized updates escape sequence which
drastically reduces flickering.
This commit is contained in:
parent
a2e47b5279
commit
b2443aa2f9
@ -435,6 +435,7 @@ screen_redraw_screen(struct client *c)
|
|||||||
|
|
||||||
flags = screen_redraw_update(c, c->flags);
|
flags = screen_redraw_update(c, c->flags);
|
||||||
screen_redraw_set_context(c, &ctx);
|
screen_redraw_set_context(c, &ctx);
|
||||||
|
tty_sync_start(&c->tty);
|
||||||
|
|
||||||
if (flags & (CLIENT_REDRAWWINDOW|CLIENT_REDRAWBORDERS)) {
|
if (flags & (CLIENT_REDRAWWINDOW|CLIENT_REDRAWBORDERS)) {
|
||||||
if (ctx.pane_status != PANE_STATUS_OFF)
|
if (ctx.pane_status != PANE_STATUS_OFF)
|
||||||
@ -448,7 +449,9 @@ screen_redraw_screen(struct client *c)
|
|||||||
screen_redraw_draw_status(&ctx);
|
screen_redraw_draw_status(&ctx);
|
||||||
if (c->overlay_draw != NULL && (flags & CLIENT_REDRAWOVERLAY))
|
if (c->overlay_draw != NULL && (flags & CLIENT_REDRAWOVERLAY))
|
||||||
c->overlay_draw(c, &ctx);
|
c->overlay_draw(c, &ctx);
|
||||||
|
|
||||||
tty_reset(&c->tty);
|
tty_reset(&c->tty);
|
||||||
|
tty_sync_end(&c->tty);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Redraw a single pane. */
|
/* Redraw a single pane. */
|
||||||
@ -461,9 +464,12 @@ screen_redraw_pane(struct client *c, struct window_pane *wp)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
screen_redraw_set_context(c, &ctx);
|
screen_redraw_set_context(c, &ctx);
|
||||||
|
tty_sync_start(&c->tty);
|
||||||
|
|
||||||
screen_redraw_draw_pane(&ctx, wp);
|
screen_redraw_draw_pane(&ctx, wp);
|
||||||
|
|
||||||
tty_reset(&c->tty);
|
tty_reset(&c->tty);
|
||||||
|
tty_sync_end(&c->tty);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw a border cell. */
|
/* Draw a border cell. */
|
||||||
|
@ -100,7 +100,8 @@ void
|
|||||||
screen_write_start(struct screen_write_ctx *ctx, struct window_pane *wp,
|
screen_write_start(struct screen_write_ctx *ctx, struct window_pane *wp,
|
||||||
struct screen *s)
|
struct screen *s)
|
||||||
{
|
{
|
||||||
u_int y;
|
struct tty_ctx ttyctx;
|
||||||
|
u_int y;
|
||||||
|
|
||||||
memset(ctx, 0, sizeof *ctx);
|
memset(ctx, 0, sizeof *ctx);
|
||||||
|
|
||||||
@ -129,18 +130,26 @@ screen_write_start(struct screen_write_ctx *ctx, struct window_pane *wp,
|
|||||||
screen_size_y(ctx->s));
|
screen_size_y(ctx->s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
screen_write_initctx(ctx, &ttyctx);
|
||||||
|
tty_write(tty_cmd_syncstart, &ttyctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finish writing. */
|
/* Finish writing. */
|
||||||
void
|
void
|
||||||
screen_write_stop(struct screen_write_ctx *ctx)
|
screen_write_stop(struct screen_write_ctx *ctx)
|
||||||
{
|
{
|
||||||
|
struct tty_ctx ttyctx;
|
||||||
|
|
||||||
screen_write_collect_end(ctx);
|
screen_write_collect_end(ctx);
|
||||||
screen_write_collect_flush(ctx, 0);
|
screen_write_collect_flush(ctx, 0);
|
||||||
|
|
||||||
log_debug("%s: %u cells (%u written, %u skipped)", __func__,
|
log_debug("%s: %u cells (%u written, %u skipped)", __func__,
|
||||||
ctx->cells, ctx->written, ctx->skipped);
|
ctx->cells, ctx->written, ctx->skipped);
|
||||||
|
|
||||||
|
screen_write_initctx(ctx, &ttyctx);
|
||||||
|
tty_write(tty_cmd_syncend, &ttyctx);
|
||||||
|
|
||||||
free(ctx->item);
|
free(ctx->item);
|
||||||
free(ctx->list); /* flush will have emptied */
|
free(ctx->list); /* flush will have emptied */
|
||||||
}
|
}
|
||||||
|
2
tmux.1
2
tmux.1
@ -5511,6 +5511,8 @@ $ printf '\e033[4 q'
|
|||||||
If
|
If
|
||||||
.Em Se
|
.Em Se
|
||||||
is not set, \&Ss with argument 0 will be used to reset the cursor style instead.
|
is not set, \&Ss with argument 0 will be used to reset the cursor style instead.
|
||||||
|
.It Em \&Sync
|
||||||
|
Show that the terminal supports synchronized updates.
|
||||||
.It Em \&Tc
|
.It Em \&Tc
|
||||||
Indicate that the terminal supports the
|
Indicate that the terminal supports the
|
||||||
.Ql direct colour
|
.Ql direct colour
|
||||||
|
6
tmux.h
6
tmux.h
@ -452,6 +452,7 @@ enum tty_code_code {
|
|||||||
TTYC_SMUL,
|
TTYC_SMUL,
|
||||||
TTYC_SMXX,
|
TTYC_SMXX,
|
||||||
TTYC_SS,
|
TTYC_SS,
|
||||||
|
TTYC_SYNC,
|
||||||
TTYC_TC,
|
TTYC_TC,
|
||||||
TTYC_TSL,
|
TTYC_TSL,
|
||||||
TTYC_U8,
|
TTYC_U8,
|
||||||
@ -1181,6 +1182,7 @@ struct tty_term {
|
|||||||
#define TERM_DECSLRM 0x4
|
#define TERM_DECSLRM 0x4
|
||||||
#define TERM_DECFRA 0x8
|
#define TERM_DECFRA 0x8
|
||||||
#define TERM_RGBCOLOURS 0x10
|
#define TERM_RGBCOLOURS 0x10
|
||||||
|
#define TERM_SYNC 0x20
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
LIST_ENTRY(tty_term) entry;
|
LIST_ENTRY(tty_term) entry;
|
||||||
@ -1949,6 +1951,8 @@ void tty_set_title(struct tty *, const char *);
|
|||||||
void tty_update_mode(struct tty *, int, struct screen *);
|
void tty_update_mode(struct tty *, int, struct screen *);
|
||||||
void tty_draw_line(struct tty *, struct window_pane *, struct screen *,
|
void tty_draw_line(struct tty *, struct window_pane *, struct screen *,
|
||||||
u_int, u_int, u_int, u_int, u_int);
|
u_int, u_int, u_int, u_int, u_int);
|
||||||
|
void tty_sync_start(struct tty *);
|
||||||
|
void tty_sync_end(struct tty *);
|
||||||
int tty_open(struct tty *, char **);
|
int tty_open(struct tty *, char **);
|
||||||
void tty_close(struct tty *);
|
void tty_close(struct tty *);
|
||||||
void tty_free(struct tty *);
|
void tty_free(struct tty *);
|
||||||
@ -1976,6 +1980,8 @@ void tty_cmd_scrolldown(struct tty *, const struct tty_ctx *);
|
|||||||
void tty_cmd_reverseindex(struct tty *, const struct tty_ctx *);
|
void tty_cmd_reverseindex(struct tty *, const struct tty_ctx *);
|
||||||
void tty_cmd_setselection(struct tty *, const struct tty_ctx *);
|
void tty_cmd_setselection(struct tty *, const struct tty_ctx *);
|
||||||
void tty_cmd_rawstring(struct tty *, const struct tty_ctx *);
|
void tty_cmd_rawstring(struct tty *, const struct tty_ctx *);
|
||||||
|
void tty_cmd_syncstart(struct tty *, const struct tty_ctx *);
|
||||||
|
void tty_cmd_syncend(struct tty *, const struct tty_ctx *);
|
||||||
|
|
||||||
/* tty-term.c */
|
/* tty-term.c */
|
||||||
extern struct tty_terms tty_terms;
|
extern struct tty_terms tty_terms;
|
||||||
|
@ -1117,7 +1117,7 @@ tty_keys_device_status_report(struct tty *tty, const char *buf, size_t len,
|
|||||||
|
|
||||||
/* Set terminal flags. */
|
/* Set terminal flags. */
|
||||||
if (strncmp(tmp, "ITERM2 ", 7) == 0)
|
if (strncmp(tmp, "ITERM2 ", 7) == 0)
|
||||||
flags |= (TERM_DECSLRM|TERM_256COLOURS|TERM_RGBCOLOURS);
|
flags |= (TERM_DECSLRM|TERM_256COLOURS|TERM_RGBCOLOURS|TERM_SYNC);
|
||||||
if (strncmp(tmp, "TMUX ", 5) == 0)
|
if (strncmp(tmp, "TMUX ", 5) == 0)
|
||||||
flags |= (TERM_256COLOURS|TERM_RGBCOLOURS);
|
flags |= (TERM_256COLOURS|TERM_RGBCOLOURS);
|
||||||
log_debug("%s: received DSR %.*s", c->name, (int)*size, buf);
|
log_debug("%s: received DSR %.*s", c->name, (int)*size, buf);
|
||||||
|
@ -260,6 +260,7 @@ static const struct tty_term_code_entry tty_term_codes[] = {
|
|||||||
[TTYC_SMUL] = { TTYCODE_STRING, "smul" },
|
[TTYC_SMUL] = { TTYCODE_STRING, "smul" },
|
||||||
[TTYC_SMXX] = { TTYCODE_STRING, "smxx" },
|
[TTYC_SMXX] = { TTYCODE_STRING, "smxx" },
|
||||||
[TTYC_SS] = { TTYCODE_STRING, "Ss" },
|
[TTYC_SS] = { TTYCODE_STRING, "Ss" },
|
||||||
|
[TTYC_SYNC] = { TTYCODE_FLAG, "Sync" },
|
||||||
[TTYC_TC] = { TTYCODE_FLAG, "Tc" },
|
[TTYC_TC] = { TTYCODE_FLAG, "Tc" },
|
||||||
[TTYC_TSL] = { TTYCODE_STRING, "tsl" },
|
[TTYC_TSL] = { TTYCODE_STRING, "tsl" },
|
||||||
[TTYC_U8] = { TTYCODE_NUMBER, "U8" },
|
[TTYC_U8] = { TTYCODE_NUMBER, "U8" },
|
||||||
@ -532,6 +533,10 @@ tty_term_find(char *name, int fd, char **cause)
|
|||||||
tty_term_has(term, TTYC_SETRGBB)))
|
tty_term_has(term, TTYC_SETRGBB)))
|
||||||
term->flags |= TERM_RGBCOLOURS;
|
term->flags |= TERM_RGBCOLOURS;
|
||||||
|
|
||||||
|
/* Set flag if terminal has synchronized updates. */
|
||||||
|
if (tty_term_flag(term, TTYC_SYNC))
|
||||||
|
term->flags |= TERM_SYNC;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Terminals without xenl (eat newline glitch) wrap at at $COLUMNS - 1
|
* Terminals without xenl (eat newline glitch) wrap at at $COLUMNS - 1
|
||||||
* rather than $COLUMNS (the cursor can never be beyond $COLUMNS - 1).
|
* rather than $COLUMNS (the cursor can never be beyond $COLUMNS - 1).
|
||||||
|
26
tty.c
26
tty.c
@ -1426,6 +1426,20 @@ tty_draw_line(struct tty *tty, struct window_pane *wp, struct screen *s,
|
|||||||
tty_update_mode(tty, tty->mode, s);
|
tty_update_mode(tty, tty->mode, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_sync_start(struct tty *tty)
|
||||||
|
{
|
||||||
|
if ((tty->term->flags|tty->term_flags) & TERM_SYNC)
|
||||||
|
tty_puts(tty, "\033P=1s\033\\");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_sync_end(struct tty *tty)
|
||||||
|
{
|
||||||
|
if ((tty->term->flags|tty->term_flags) & TERM_SYNC)
|
||||||
|
tty_puts(tty, "\033P=2s\033\\");
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
tty_client_ready(struct client *c, struct window_pane *wp)
|
tty_client_ready(struct client *c, struct window_pane *wp)
|
||||||
{
|
{
|
||||||
@ -1919,6 +1933,18 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx)
|
|||||||
tty_invalidate(tty);
|
tty_invalidate(tty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_cmd_syncstart(struct tty *tty, __unused const struct tty_ctx *ctx)
|
||||||
|
{
|
||||||
|
tty_sync_start(tty);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_cmd_syncend(struct tty *tty, __unused const struct tty_ctx *ctx)
|
||||||
|
{
|
||||||
|
tty_sync_end(tty);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tty_cell(struct tty *tty, const struct grid_cell *gc, struct window_pane *wp)
|
tty_cell(struct tty *tty, const struct grid_cell *gc, struct window_pane *wp)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user