From 49b698ac6fc6f464d06223ef139ec4d7cd7b40c0 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 5 Oct 2021 12:46:02 +0000 Subject: [PATCH] Separate "very visible" flag from blinking flag, it should not affect DECSCUSR. GitHub issue 2891. --- usr.bin/tmux/input.c | 10 +-- usr.bin/tmux/job.c | 3 +- usr.bin/tmux/screen.c | 20 +++--- usr.bin/tmux/tmux.h | 6 +- usr.bin/tmux/tty.c | 161 ++++++++++++++++++++---------------------- 5 files changed, 99 insertions(+), 101 deletions(-) diff --git a/usr.bin/tmux/input.c b/usr.bin/tmux/input.c index 51d142cdd0e..8e0e89d12cf 100644 --- a/usr.bin/tmux/input.c +++ b/usr.bin/tmux/input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: input.c,v 1.192 2021/08/14 16:26:29 nicm Exp $ */ +/* $OpenBSD: input.c,v 1.193 2021/10/05 12:46:02 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -1646,7 +1646,7 @@ input_csi_dispatch_rm(struct input_ctx *ictx) screen_write_mode_clear(sctx, MODE_INSERT); break; case 34: - screen_write_mode_set(sctx, MODE_BLINKING); + screen_write_mode_set(sctx, MODE_CURSOR_VERY_VISIBLE); break; default: log_debug("%s: unknown '%c'", __func__, ictx->ch); @@ -1682,7 +1682,7 @@ input_csi_dispatch_rm_private(struct input_ctx *ictx) screen_write_mode_clear(sctx, MODE_WRAP); break; case 12: - screen_write_mode_clear(sctx, MODE_BLINKING); + screen_write_mode_clear(sctx, MODE_CURSOR_BLINKING); break; case 25: /* TCEM */ screen_write_mode_clear(sctx, MODE_CURSOR); @@ -1734,7 +1734,7 @@ input_csi_dispatch_sm(struct input_ctx *ictx) screen_write_mode_set(sctx, MODE_INSERT); break; case 34: - screen_write_mode_clear(sctx, MODE_BLINKING); + screen_write_mode_clear(sctx, MODE_CURSOR_VERY_VISIBLE); break; default: log_debug("%s: unknown '%c'", __func__, ictx->ch); @@ -1771,7 +1771,7 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx) screen_write_mode_set(sctx, MODE_WRAP); break; case 12: - screen_write_mode_set(sctx, MODE_BLINKING); + screen_write_mode_set(sctx, MODE_CURSOR_BLINKING); break; case 25: /* TCEM */ screen_write_mode_set(sctx, MODE_CURSOR); diff --git a/usr.bin/tmux/job.c b/usr.bin/tmux/job.c index df0774240ac..314776f873b 100644 --- a/usr.bin/tmux/job.c +++ b/usr.bin/tmux/job.c @@ -1,4 +1,4 @@ -/* $OpenBSD: job.c,v 1.62 2021/08/13 19:55:11 nicm Exp $ */ +/* $OpenBSD: job.c,v 1.63 2021/10/05 12:46:02 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -339,6 +339,7 @@ job_check_died(pid_t pid, int status) log_debug("job died %p: %s, pid %ld", job, job->cmd, (long) job->pid); job->status = status; + log_debug("job %p status %d", job, job->status); if (job->state == JOB_CLOSED) { if (job->completecb != NULL) diff --git a/usr.bin/tmux/screen.c b/usr.bin/tmux/screen.c index 1165756ddc5..21d9d13b298 100644 --- a/usr.bin/tmux/screen.c +++ b/usr.bin/tmux/screen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: screen.c,v 1.75 2021/09/09 06:57:48 nicm Exp $ */ +/* $OpenBSD: screen.c,v 1.76 2021/10/05 12:46:02 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -163,27 +163,27 @@ screen_set_cursor_style(struct screen *s, u_int style) break; case 1: s->cstyle = SCREEN_CURSOR_BLOCK; - s->mode |= MODE_BLINKING; + s->mode |= MODE_CURSOR_BLINKING; break; case 2: s->cstyle = SCREEN_CURSOR_BLOCK; - s->mode &= ~MODE_BLINKING; + s->mode &= ~MODE_CURSOR_BLINKING; break; case 3: s->cstyle = SCREEN_CURSOR_UNDERLINE; - s->mode |= MODE_BLINKING; + s->mode |= MODE_CURSOR_BLINKING; break; case 4: s->cstyle = SCREEN_CURSOR_UNDERLINE; - s->mode &= ~MODE_BLINKING; + s->mode &= ~MODE_CURSOR_BLINKING; break; case 5: s->cstyle = SCREEN_CURSOR_BAR; - s->mode |= MODE_BLINKING; + s->mode |= MODE_CURSOR_BLINKING; break; case 6: s->cstyle = SCREEN_CURSOR_BAR; - s->mode &= ~MODE_BLINKING; + s->mode &= ~MODE_CURSOR_BLINKING; break; } } @@ -680,8 +680,10 @@ screen_mode_to_string(int mode) strlcat(tmp, "MOUSE_STANDARD,", sizeof tmp); if (mode & MODE_MOUSE_BUTTON) strlcat(tmp, "MOUSE_BUTTON,", sizeof tmp); - if (mode & MODE_BLINKING) - strlcat(tmp, "BLINKING,", sizeof tmp); + if (mode & MODE_CURSOR_BLINKING) + strlcat(tmp, "CURSOR_BLINKING,", sizeof tmp); + if (mode & MODE_CURSOR_VERY_VISIBLE) + strlcat(tmp, "CURSOR_VERY_VISIBLE,", sizeof tmp); if (mode & MODE_MOUSE_UTF8) strlcat(tmp, "UTF8,", sizeof tmp); if (mode & MODE_MOUSE_SGR) diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index b47722682bf..2ce80b57398 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1142 2021/09/10 15:03:18 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1143 2021/10/05 12:46:02 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -520,7 +520,7 @@ enum tty_code_code { #define MODE_WRAP 0x10 #define MODE_MOUSE_STANDARD 0x20 #define MODE_MOUSE_BUTTON 0x40 -#define MODE_BLINKING 0x80 +#define MODE_CURSOR_BLINKING 0x80 #define MODE_MOUSE_UTF8 0x100 #define MODE_MOUSE_SGR 0x200 #define MODE_BRACKETPASTE 0x400 @@ -529,10 +529,12 @@ enum tty_code_code { #define MODE_ORIGIN 0x2000 #define MODE_CRLF 0x4000 #define MODE_KEXTENDED 0x8000 +#define MODE_CURSOR_VERY_VISIBLE 0x10000 #define ALL_MODES 0xffffff #define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ALL) #define MOTION_MOUSE_MODES (MODE_MOUSE_BUTTON|MODE_MOUSE_ALL) +#define CURSOR_MODES (MODE_CURSOR|MODE_CURSOR_BLINKING|MODE_CURSOR_VERY_VISIBLE) /* A single UTF-8 character. */ typedef u_int utf8_char; diff --git a/usr.bin/tmux/tty.c b/usr.bin/tmux/tty.c index 8be5aadb8ee..25eabdb45c4 100644 --- a/usr.bin/tmux/tty.c +++ b/usr.bin/tmux/tty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty.c,v 1.403 2021/08/17 11:20:13 nicm Exp $ */ +/* $OpenBSD: tty.c,v 1.404 2021/10/05 12:46:02 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -314,7 +314,7 @@ tty_start_tty(struct tty *tty) tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 0; if (tcsetattr(c->fd, TCSANOW, &tio) == 0) - tcflush(c->fd, TCIOFLUSH); + tcflush(c->fd, TCOFLUSH); tty_putcode(tty, TTYC_SMCUP); @@ -658,12 +658,83 @@ tty_force_cursor_colour(struct tty *tty, const char *ccolour) tty->ccolour = xstrdup(ccolour); } +static void +tty_update_cursor(struct tty *tty, int mode, int changed, struct screen *s) +{ + enum screen_cursor_style cstyle; + + /* Set cursor colour if changed. */ + if (s != NULL && strcmp(s->ccolour, tty->ccolour) != 0) + tty_force_cursor_colour(tty, s->ccolour); + + /* If cursor is off, set as invisible. */ + if (~mode & MODE_CURSOR) { + if (changed & MODE_CURSOR) + tty_putcode(tty, TTYC_CIVIS); + return; + } + + /* Check if blinking or very visible flag changed or style changed. */ + if (s == NULL) + cstyle = tty->cstyle; + else + cstyle = s->cstyle; + if ((changed & CURSOR_MODES) == 0 && cstyle == tty->cstyle) + return; + + /* + * Set cursor style. If an explicit style has been set with DECSCUSR, + * set it if supported, otherwise send cvvis for blinking styles. + * + * If no style, has been set (SCREEN_CURSOR_DEFAULT), then send cvvis + * if either the blinking or very visible flags are set. + */ + tty_putcode(tty, TTYC_CNORM); + switch (cstyle) { + case SCREEN_CURSOR_DEFAULT: + if (tty_term_has(tty->term, TTYC_SE)) + tty_putcode(tty, TTYC_SE); + else + tty_putcode1(tty, TTYC_SS, 0); + if (mode & (MODE_CURSOR_BLINKING|MODE_CURSOR_VERY_VISIBLE)) + tty_putcode(tty, TTYC_CVVIS); + break; + case SCREEN_CURSOR_BLOCK: + if (tty_term_has(tty->term, TTYC_SS)) { + if (mode & MODE_CURSOR_BLINKING) + tty_putcode1(tty, TTYC_SS, 1); + else + tty_putcode1(tty, TTYC_SS, 2); + } else if (mode & MODE_CURSOR_BLINKING) + tty_putcode(tty, TTYC_CVVIS); + break; + case SCREEN_CURSOR_UNDERLINE: + if (tty_term_has(tty->term, TTYC_SS)) { + if (mode & MODE_CURSOR_BLINKING) + tty_putcode1(tty, TTYC_SS, 3); + else + tty_putcode1(tty, TTYC_SS, 4); + } else if (mode & MODE_CURSOR_BLINKING) + tty_putcode(tty, TTYC_CVVIS); + break; + case SCREEN_CURSOR_BAR: + if (tty_term_has(tty->term, TTYC_SS)) { + if (mode & MODE_CURSOR_BLINKING) + tty_putcode1(tty, TTYC_SS, 5); + else + tty_putcode1(tty, TTYC_SS, 6); + } else if (mode & MODE_CURSOR_BLINKING) + tty_putcode(tty, TTYC_CVVIS); + break; + } + tty->cstyle = cstyle; + } + void tty_update_mode(struct tty *tty, int mode, struct screen *s) { - struct client *c = tty->client; - int changed; - enum screen_cursor_style cstyle = tty->cstyle; + struct client *c = tty->client; + int changed; if (tty->flags & TTY_NOCURSOR) mode &= ~MODE_CURSOR; @@ -676,85 +747,7 @@ tty_update_mode(struct tty *tty, int mode, struct screen *s) screen_mode_to_string(mode)); } - if (s != NULL) { - if (strcmp(s->ccolour, tty->ccolour) != 0) - tty_force_cursor_colour(tty, s->ccolour); - cstyle = s->cstyle; - } - if (~mode & MODE_CURSOR) { - /* Cursor now off - set as invisible. */ - if (changed & MODE_CURSOR) - tty_putcode(tty, TTYC_CIVIS); - } else if ((changed & (MODE_CURSOR|MODE_BLINKING)) || - cstyle != tty->cstyle) { - /* - * Cursor now on, blinking flag changed or style changed. Start - * by setting the cursor to normal. - */ - tty_putcode(tty, TTYC_CNORM); - switch (cstyle) { - case SCREEN_CURSOR_DEFAULT: - /* - * If the old style wasn't default, then reset it to - * default. - */ - if (tty->cstyle != SCREEN_CURSOR_DEFAULT) { - if (tty_term_has(tty->term, TTYC_SE)) - tty_putcode(tty, TTYC_SE); - else - tty_putcode1(tty, TTYC_SS, 0); - } - - /* Set the cursor as very visible if necessary. */ - if (mode & MODE_BLINKING) - tty_putcode(tty, TTYC_CVVIS); - break; - case SCREEN_CURSOR_BLOCK: - /* - * Set style to either block blinking (1) or steady (2) - * if supported, otherwise just check the blinking - * flag. - */ - if (tty_term_has(tty->term, TTYC_SS)) { - if (mode & MODE_BLINKING) - tty_putcode1(tty, TTYC_SS, 1); - else - tty_putcode1(tty, TTYC_SS, 2); - } else if (mode & MODE_BLINKING) - tty_putcode(tty, TTYC_CVVIS); - break; - case SCREEN_CURSOR_UNDERLINE: - /* - * Set style to either underline blinking (3) or steady - * (4) if supported, otherwise just check the blinking - * flag. - */ - if (tty_term_has(tty->term, TTYC_SS)) { - if (mode & MODE_BLINKING) - tty_putcode1(tty, TTYC_SS, 3); - else - tty_putcode1(tty, TTYC_SS, 4); - } else if (mode & MODE_BLINKING) - tty_putcode(tty, TTYC_CVVIS); - break; - case SCREEN_CURSOR_BAR: - /* - * Set style to either bar blinking (5) or steady (6) - * if supported, otherwise just check the blinking - * flag. - */ - if (tty_term_has(tty->term, TTYC_SS)) { - if (mode & MODE_BLINKING) - tty_putcode1(tty, TTYC_SS, 5); - else - tty_putcode1(tty, TTYC_SS, 6); - } else if (mode & MODE_BLINKING) - tty_putcode(tty, TTYC_CVVIS); - break; - } - tty->cstyle = cstyle; - } - + tty_update_cursor(tty, mode, changed, s); if ((changed & ALL_MOUSE_MODES) && tty_term_has(tty->term, TTYC_KMOUS)) { /* -- 2.20.1