Fix so tmux correctly sends the cvvis (cursor very visible) capability
authornicm <nicm@openbsd.org>
Fri, 12 Mar 2021 08:39:17 +0000 (08:39 +0000)
committernicm <nicm@openbsd.org>
Fri, 12 Mar 2021 08:39:17 +0000 (08:39 +0000)
rather than sending it and then immediately undoing it with cnorm. Also
turn it off when the cursor shape is changed like xterm.

usr.bin/tmux/screen.c
usr.bin/tmux/tty.c

index d5dfbff..a01ddb3 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: screen.c,v 1.69 2021/01/26 09:32:52 nicm Exp $ */
+/* $OpenBSD: screen.c,v 1.70 2021/03/12 08:39:17 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -154,8 +154,10 @@ screen_reset_tabs(struct screen *s)
 void
 screen_set_cursor_style(struct screen *s, u_int style)
 {
-       if (style <= 6)
+       if (style <= 6) {
                s->cstyle = style;
+               s->mode &= ~MODE_BLINKING;
+       }
 }
 
 /* Set screen cursor colour. */
index 6e7e97d..ba87484 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tty.c,v 1.389 2021/02/17 07:18:36 nicm Exp $ */
+/* $OpenBSD: tty.c,v 1.390 2021/03/12 08:39:17 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -670,19 +670,10 @@ 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);
 
-       if (changed & MODE_BLINKING) {
-               if (tty_term_has(tty->term, TTYC_CVVIS))
-                       tty_putcode(tty, TTYC_CVVIS);
-               else
-                       tty_putcode(tty, TTYC_CNORM);
-               changed |= MODE_CURSOR;
-       }
-       if (changed & MODE_CURSOR) {
-               if (mode & MODE_CURSOR)
-                       tty_putcode(tty, TTYC_CNORM);
-               else
-                       tty_putcode(tty, TTYC_CIVIS);
-       }
+       /*
+        * 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))
@@ -691,7 +682,28 @@ tty_update_mode(struct tty *tty, int mode, struct screen *s)
                                tty_putcode1(tty, TTYC_SS, s->cstyle);
                }
                tty->cstyle = s->cstyle;
+               changed |= (MODE_CURSOR|MODE_BLINKING);
        }
+
+       /*
+        * 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)
+                       tty_putcode(tty, TTYC_CIVIS);
+               else if (mode & MODE_BLINKING) {
+                       tty_putcode(tty, TTYC_CNORM);
+                       if (tty_term_has(tty->term, TTYC_CVVIS))
+                               tty_putcode(tty, TTYC_CVVIS);
+               } else
+                       tty_putcode(tty, TTYC_CNORM);
+       }
+
        if ((changed & ALL_MOUSE_MODES) &&
            tty_term_has(tty->term, TTYC_KMOUS)) {
                /*