summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2021-06-10 07:36:48 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2021-06-10 07:36:48 +0000
commit16f0ab9fa2eaba353a102ce461de27bffbf6e37e (patch)
tree6c2d656fa43ff62af94556589a55d525ccbd28a3
parent0a7abb213b1253e257464415b26e0488cb726560 (diff)
Change cursor style handling so tmux understands which sequences contain
blinking and sets the flag appropriately, means that it works whether cnorm disables blinking or not. GitHub issue 2682.
-rw-r--r--usr.bin/tmux/screen.c34
-rw-r--r--usr.bin/tmux/tmux.h16
-rw-r--r--usr.bin/tmux/tty.c119
3 files changed, 123 insertions, 46 deletions
diff --git a/usr.bin/tmux/screen.c b/usr.bin/tmux/screen.c
index cb8aa867382..b578902bd92 100644
--- a/usr.bin/tmux/screen.c
+++ b/usr.bin/tmux/screen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: screen.c,v 1.71 2021/06/10 07:24:10 nicm Exp $ */
+/* $OpenBSD: screen.c,v 1.72 2021/06/10 07:36:47 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -81,7 +81,7 @@ screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit)
s->titles = NULL;
s->path = NULL;
- s->cstyle = 0;
+ s->cstyle = SCREEN_CURSOR_DEFAULT;
s->ccolour = xstrdup("");
s->tabs = NULL;
s->sel = NULL;
@@ -156,9 +156,35 @@ screen_reset_tabs(struct screen *s)
void
screen_set_cursor_style(struct screen *s, u_int style)
{
- if (style <= 6) {
- s->cstyle = style;
+ switch (style)
+ {
+ case 0:
+ s->cstyle = SCREEN_CURSOR_DEFAULT;
+ break;
+ case 1:
+ s->cstyle = SCREEN_CURSOR_BLOCK;
+ s->mode |= MODE_BLINKING;
+ break;
+ case 2:
+ s->cstyle = SCREEN_CURSOR_BLOCK;
s->mode &= ~MODE_BLINKING;
+ break;
+ case 3:
+ s->cstyle = SCREEN_CURSOR_UNDERLINE;
+ s->mode |= MODE_BLINKING;
+ break;
+ case 4:
+ s->cstyle = SCREEN_CURSOR_UNDERLINE;
+ s->mode &= ~MODE_BLINKING;
+ break;
+ case 5:
+ s->cstyle = SCREEN_CURSOR_BAR;
+ s->mode |= MODE_BLINKING;
+ break;
+ case 6:
+ s->cstyle = SCREEN_CURSOR_BAR;
+ s->mode &= ~MODE_BLINKING;
+ break;
}
}
diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h
index 21e522ad675..67f7d0eeb21 100644
--- a/usr.bin/tmux/tmux.h
+++ b/usr.bin/tmux/tmux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.1105 2021/06/10 07:33:41 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.1106 2021/06/10 07:36:47 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -794,6 +794,14 @@ struct style {
enum style_default_type default_type;
};
+/* Cursor style. */
+enum screen_cursor_style {
+ SCREEN_CURSOR_DEFAULT,
+ SCREEN_CURSOR_BLOCK,
+ SCREEN_CURSOR_UNDERLINE,
+ SCREEN_CURSOR_BAR
+};
+
/* Virtual screen. */
struct screen_sel;
struct screen_titles;
@@ -807,8 +815,8 @@ struct screen {
u_int cx; /* cursor x */
u_int cy; /* cursor y */
- u_int cstyle; /* cursor style */
- char *ccolour; /* cursor colour string */
+ enum screen_cursor_style cstyle; /* cursor style */
+ char *ccolour; /* cursor colour */
u_int rupper; /* scroll region top */
u_int rlower; /* scroll region bottom */
@@ -1296,7 +1304,7 @@ struct tty {
u_int cx;
u_int cy;
- u_int cstyle;
+ enum screen_cursor_style cstyle;
char *ccolour;
int oflag;
diff --git a/usr.bin/tmux/tty.c b/usr.bin/tmux/tty.c
index ba87484b588..58c4792ba61 100644
--- a/usr.bin/tmux/tty.c
+++ b/usr.bin/tmux/tty.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tty.c,v 1.390 2021/03/12 08:39:17 nicm Exp $ */
+/* $OpenBSD: tty.c,v 1.391 2021/06/10 07:36:47 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -98,7 +98,7 @@ tty_init(struct tty *tty, struct client *c)
memset(tty, 0, sizeof *tty);
tty->client = c;
- tty->cstyle = 0;
+ tty->cstyle = SCREEN_CURSOR_DEFAULT;
tty->ccolour = xstrdup("");
if (tcgetattr(c->fd, &tty->tio) != 0)
@@ -392,10 +392,10 @@ tty_stop_tty(struct tty *tty)
tty_raw(tty, tty_term_string(tty->term, TTYC_SGR0));
tty_raw(tty, tty_term_string(tty->term, TTYC_RMKX));
tty_raw(tty, tty_term_string(tty->term, TTYC_CLEAR));
- if (tty_term_has(tty->term, TTYC_SS) && tty->cstyle != 0) {
+ if (tty->cstyle != SCREEN_CURSOR_DEFAULT) {
if (tty_term_has(tty->term, TTYC_SE))
tty_raw(tty, tty_term_string(tty->term, TTYC_SE));
- else
+ else if (tty_term_has(tty->term, TTYC_SS))
tty_raw(tty, tty_term_string1(tty->term, TTYC_SS, 0));
}
if (tty->mode & MODE_BRACKETPASTE)
@@ -657,11 +657,9 @@ tty_force_cursor_colour(struct tty *tty, const char *ccolour)
void
tty_update_mode(struct tty *tty, int mode, struct screen *s)
{
- struct client *c = tty->client;
- int changed;
-
- if (s != NULL && strcmp(s->ccolour, tty->ccolour) != 0)
- tty_force_cursor_colour(tty, s->ccolour);
+ struct client *c = tty->client;
+ int changed;
+ enum screen_cursor_style cstyle = tty->cstyle;
if (tty->flags & TTY_NOCURSOR)
mode &= ~MODE_CURSOR;
@@ -670,38 +668,83 @@ tty_update_mode(struct tty *tty, int mode, struct screen *s)
if (changed != 0)
log_debug("%s: update mode %x to %x", c->name, tty->mode, mode);
- /*
- * The cursor blinking flag can be reset by setting the cursor style, so
- * set the style first.
- */
- if (s != NULL && tty->cstyle != s->cstyle) {
- if (tty_term_has(tty->term, TTYC_SS)) {
- if (s->cstyle == 0 && tty_term_has(tty->term, TTYC_SE))
- tty_putcode(tty, TTYC_SE);
- else
- tty_putcode1(tty, TTYC_SS, s->cstyle);
- }
- tty->cstyle = s->cstyle;
- changed |= (MODE_CURSOR|MODE_BLINKING);
+ if (s != NULL) {
+ if (strcmp(s->ccolour, tty->ccolour) != 0)
+ tty_force_cursor_colour(tty, s->ccolour);
+ cstyle = s->cstyle;
}
-
- /*
- * Cursor invisible (RM ?25) overrides cursor blinking (SM ?12 or RM
- * 34), and we need to be careful not send cnorm after cvvis since it
- * can undo it.
- */
- if (changed & (MODE_CURSOR|MODE_BLINKING)) {
- log_debug("%s: cursor %s, %sblinking", __func__,
- (mode & MODE_CURSOR) ? "on" : "off",
- (mode & MODE_BLINKING) ? "" : "not ");
- if (~mode & MODE_CURSOR)
+ if (~mode & MODE_CURSOR) {
+ /* Cursor now off - set as invisible. */
+ if (changed & MODE_CURSOR)
tty_putcode(tty, TTYC_CIVIS);
- else if (mode & MODE_BLINKING) {
- tty_putcode(tty, TTYC_CNORM);
- if (tty_term_has(tty->term, TTYC_CVVIS))
+ } 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);
- } else
- tty_putcode(tty, TTYC_CNORM);
+ 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;
}
if ((changed & ALL_MOUSE_MODES) &&