Add a cursor-colour option, from Alexis Hildebrandt in GitHub issue
authornicm <nicm@openbsd.org>
Mon, 1 Nov 2021 09:34:49 +0000 (09:34 +0000)
committernicm <nicm@openbsd.org>
Mon, 1 Nov 2021 09:34:49 +0000 (09:34 +0000)
2959.

usr.bin/tmux/input.c
usr.bin/tmux/options-table.c
usr.bin/tmux/options.c
usr.bin/tmux/screen.c
usr.bin/tmux/tmux.1
usr.bin/tmux/tmux.h
usr.bin/tmux/tty.c

index 8e0e89d..90f0bf7 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: input.c,v 1.193 2021/10/05 12:46:02 nicm Exp $ */
+/* $OpenBSD: input.c,v 1.194 2021/11/01 09:34:49 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -137,10 +137,12 @@ static void       input_reset_cell(struct input_ctx *);
 static void    input_osc_4(struct input_ctx *, const char *);
 static void    input_osc_10(struct input_ctx *, const char *);
 static void    input_osc_11(struct input_ctx *, const char *);
+static void    input_osc_12(struct input_ctx *, const char *);
 static void    input_osc_52(struct input_ctx *, const char *);
 static void    input_osc_104(struct input_ctx *, const char *);
 static void    input_osc_110(struct input_ctx *, const char *);
 static void    input_osc_111(struct input_ctx *, const char *);
+static void    input_osc_112(struct input_ctx *, const char *);
 
 /* Transition entry/exit handlers. */
 static void    input_clear(struct input_ctx *);
@@ -2310,8 +2312,7 @@ input_exit_osc(struct input_ctx *ictx)
                input_osc_11(ictx, p);
                break;
        case 12:
-               if (utf8_isvalid(p) && *p != '?') /* ? is colour request */
-                       screen_set_cursor_colour(sctx->s, p);
+               input_osc_12(ictx, p);
                break;
        case 52:
                input_osc_52(ictx, p);
@@ -2326,8 +2327,7 @@ input_exit_osc(struct input_ctx *ictx)
                input_osc_111(ictx, p);
                break;
        case 112:
-               if (*p == '\0') /* no arguments allowed */
-                       screen_set_cursor_colour(sctx->s, "");
+               input_osc_112(ictx, p);
                break;
        default:
                log_debug("%s: unknown '%u'", __func__, option);
@@ -2489,7 +2489,9 @@ input_osc_colour_reply(struct input_ctx *ictx, u_int n, int c)
     u_char      r, g, b;
     const char *end;
 
-    if (c == 8 || (~c & COLOUR_FLAG_RGB))
+    if (c != -1)
+           c = colour_force_rgb(c);
+    if (c == -1)
            return;
     colour_split_rgb(c, &r, &g, &b);
 
@@ -2564,7 +2566,7 @@ input_osc_10(struct input_ctx *ictx, const char *p)
        }
 }
 
-/* Handle the OSC 110 sequence for resetting background colour. */
+/* Handle the OSC 110 sequence for resetting foreground colour. */
 static void
 input_osc_110(struct input_ctx *ictx, const char *p)
 {
@@ -2624,6 +2626,39 @@ input_osc_111(struct input_ctx *ictx, const char *p)
        }
 }
 
+/* Handle the OSC 12 sequence for setting and querying cursor colour. */
+static void
+input_osc_12(struct input_ctx *ictx, const char *p)
+{
+       struct window_pane      *wp = ictx->wp;
+       int                      c;
+
+       if (strcmp(p, "?") == 0) {
+               if (wp != NULL) {
+                       c = ictx->ctx.s->ccolour;
+                       if (c == -1)
+                               c = ictx->ctx.s->default_ccolour;
+                       input_osc_colour_reply(ictx, 12, c);
+               }
+               return;
+       }
+
+       if ((c = input_osc_parse_colour(p)) == -1) {
+               log_debug("bad OSC 12: %s", p);
+               return;
+       }
+       screen_set_cursor_colour(ictx->ctx.s, c);
+}
+
+/* Handle the OSC 112 sequence for resetting cursor colour. */
+static void
+input_osc_112(struct input_ctx *ictx, const char *p)
+{
+       if (*p == '\0') /* no arguments allowed */
+               screen_set_cursor_colour(ictx->ctx.s, -1);
+}
+
+
 /* Handle the OSC 52 sequence for setting the clipboard. */
 static void
 input_osc_52(struct input_ctx *ictx, const char *p)
index c435480..d0511e2 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: options-table.c,v 1.152 2021/10/14 13:19:01 nicm Exp $ */
+/* $OpenBSD: options-table.c,v 1.153 2021/11/01 09:34:49 nicm Exp $ */
 
 /*
  * Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -188,6 +188,7 @@ const struct options_name_map options_other_names[] = {
        { "display-panes-color", "display-panes-colour" },
        { "display-panes-active-color", "display-panes-active-colour" },
        { "clock-mode-color", "clock-mode-colour" },
+       { "cursor-color", "cursor-colour" },
        { "pane-colors", "pane-colours" },
        { NULL, NULL }
 };
@@ -235,6 +236,13 @@ const struct options_table_entry options_table[] = {
                  "If empty, no command is run."
        },
 
+       { .name = "cursor-colour",
+         .type = OPTIONS_TABLE_COLOUR,
+         .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
+         .default_num = -1,
+         .text = "Colour of the cursor."
+       },
+
        { .name = "default-terminal",
          .type = OPTIONS_TABLE_STRING,
          .scope = OPTIONS_TABLE_SERVER,
index 10bb1f3..a4af7cd 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: options.c,v 1.65 2021/10/14 13:19:01 nicm Exp $ */
+/* $OpenBSD: options.c,v 1.66 2021/11/01 09:34:49 nicm Exp $ */
 
 /*
  * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1106,15 +1106,22 @@ options_push_changes(const char *name)
        struct session          *s;
        struct window           *w;
        struct window_pane      *wp;
+       int                      c;
 
        if (strcmp(name, "automatic-rename") == 0) {
                RB_FOREACH(w, windows, &windows) {
                        if (w->active == NULL)
                                continue;
-                       if (options_get_number(w->options, "automatic-rename"))
+                       if (options_get_number(w->options, name))
                                w->active->flags |= PANE_CHANGED;
                }
        }
+       if (strcmp(name, "cursor-colour") == 0) {
+               RB_FOREACH(wp, window_pane_tree, &all_window_panes) {
+                       c = options_get_number(wp->options, name);
+                       wp->screen->default_ccolour = c;
+               }
+       }
        if (strcmp(name, "key-table") == 0) {
                TAILQ_FOREACH(loop, &clients, entry)
                        server_client_set_key_table(loop, NULL);
index 21d9d13..0ac7f62 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: screen.c,v 1.76 2021/10/05 12:46:02 nicm Exp $ */
+/* $OpenBSD: screen.c,v 1.77 2021/11/01 09:34:49 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -82,7 +82,8 @@ screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit)
        s->path = NULL;
 
        s->cstyle = SCREEN_CURSOR_DEFAULT;
-       s->ccolour = xstrdup("");
+       s->ccolour = -1;
+       s->default_ccolour = -1;
        s->tabs = NULL;
        s->sel = NULL;
 
@@ -126,7 +127,6 @@ screen_free(struct screen *s)
        free(s->tabs);
        free(s->path);
        free(s->title);
-       free(s->ccolour);
 
        if (s->write_list != NULL)
                screen_write_free_list(s);
@@ -190,10 +190,9 @@ screen_set_cursor_style(struct screen *s, u_int style)
 
 /* Set screen cursor colour. */
 void
-screen_set_cursor_colour(struct screen *s, const char *colour)
+screen_set_cursor_colour(struct screen *s, int colour)
 {
-       free(s->ccolour);
-       s->ccolour = xstrdup(colour);
+       s->ccolour = colour;
 }
 
 /* Set screen title. */
index d0107c4..141461d 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tmux.1,v 1.867 2021/10/25 21:21:16 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.868 2021/11/01 09:34:49 nicm Exp $
 .\"
 .\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
 .\"
@@ -14,7 +14,7 @@
 .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: October 25 2021 $
+.Dd $Mdocdate: November 1 2021 $
 .Dt TMUX 1
 .Os
 .Sh NAME
@@ -4416,6 +4416,9 @@ The alternate screen feature preserves the contents of the window when an
 interactive application starts and restores it on exit, so that any output
 visible before the application starts reappears unchanged after it exits.
 .Pp
+.It Ic cursor-colour Ar colour
+Set the colour of the cursor.
+.Pp
 .It Ic pane-colours[] Ar colour
 The default colour palette.
 Each entry in the array defines the colour
index 9c66307..0c7ddd2 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.1152 2021/10/28 18:54:33 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.1153 2021/11/01 09:34:49 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -779,7 +779,8 @@ struct screen {
        u_int                            cy;      /* cursor y */
 
        enum screen_cursor_style         cstyle;  /* cursor style */
-       char                            *ccolour; /* cursor colour */
+       int                              ccolour; /* cursor colour */
+       int                              default_ccolour;
 
        u_int                            rupper;  /* scroll region top */
        u_int                            rlower;  /* scroll region bottom */
@@ -1276,7 +1277,7 @@ struct tty {
        u_int            cx;
        u_int            cy;
        enum screen_cursor_style cstyle;
-       char            *ccolour;
+       int              ccolour;
 
        int              oflag;
        u_int            oox;
@@ -2793,7 +2794,7 @@ void       screen_reinit(struct screen *);
 void    screen_free(struct screen *);
 void    screen_reset_tabs(struct screen *);
 void    screen_set_cursor_style(struct screen *, u_int);
-void    screen_set_cursor_colour(struct screen *, const char *);
+void    screen_set_cursor_colour(struct screen *, int);
 int     screen_set_title(struct screen *, const char *);
 void    screen_set_path(struct screen *, const char *);
 void    screen_push_title(struct screen *);
index 480f402..12c0ff3 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tty.c,v 1.409 2021/10/28 18:57:06 nicm Exp $ */
+/* $OpenBSD: tty.c,v 1.410 2021/11/01 09:34:49 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -38,7 +38,7 @@ static int    tty_client_ready(struct client *);
 
 static void    tty_set_italics(struct tty *);
 static int     tty_try_colour(struct tty *, int, const char *);
-static void    tty_force_cursor_colour(struct tty *, const char *);
+static void    tty_force_cursor_colour(struct tty *, int);
 static void    tty_cursor_pane(struct tty *, const struct tty_ctx *, u_int,
                    u_int);
 static void    tty_cursor_pane_unless_wrap(struct tty *,
@@ -105,7 +105,7 @@ tty_init(struct tty *tty, struct client *c)
        tty->client = c;
 
        tty->cstyle = SCREEN_CURSOR_DEFAULT;
-       tty->ccolour = xstrdup("");
+       tty->ccolour = -1;
 
        if (tcgetattr(c->fd, &tty->tio) != 0)
                return (-1);
@@ -341,8 +341,8 @@ tty_start_tty(struct tty *tty)
        tty->flags |= TTY_STARTED;
        tty_invalidate(tty);
 
-       if (*tty->ccolour != '\0')
-               tty_force_cursor_colour(tty, "");
+       if (tty->ccolour != -1)
+               tty_force_cursor_colour(tty, -1);
 
        tty->mouse_drag_flag = 0;
        tty->mouse_drag_update = NULL;
@@ -406,7 +406,7 @@ tty_stop_tty(struct tty *tty)
        }
        if (tty->mode & MODE_BRACKETPASTE)
                tty_raw(tty, tty_term_string(tty->term, TTYC_DSBP));
-       if (*tty->ccolour != '\0')
+       if (tty->ccolour != -1)
                tty_raw(tty, tty_term_string(tty->term, TTYC_CR));
 
        tty_raw(tty, tty_term_string(tty->term, TTYC_CNORM));
@@ -451,7 +451,6 @@ void
 tty_free(struct tty *tty)
 {
        tty_close(tty);
-       free(tty->ccolour);
 }
 
 void
@@ -650,24 +649,38 @@ tty_set_title(struct tty *tty, const char *title)
 }
 
 static void
-tty_force_cursor_colour(struct tty *tty, const char *ccolour)
+tty_force_cursor_colour(struct tty *tty, int c)
 {
-       if (*ccolour == '\0')
+       u_char  r, g, b;
+       char    s[13] = "";
+
+       if (c != -1)
+               c = colour_force_rgb(c);
+       if (c == tty->ccolour)
+               return;
+       if (c == -1)
                tty_putcode(tty, TTYC_CR);
-       else
-               tty_putcode_ptr1(tty, TTYC_CS, ccolour);
-       free(tty->ccolour);
-       tty->ccolour = xstrdup(ccolour);
+       else {
+               colour_split_rgb(c, &r, &g, &b);
+               xsnprintf(s, sizeof s, "rgb:%02hhx/%02hhx/%02hhx", r, g, b);
+               tty_putcode_ptr1(tty, TTYC_CS, s);
+       }
+       tty->ccolour = c;
 }
 
 static void
 tty_update_cursor(struct tty *tty, int mode, int changed, struct screen *s)
 {
-       enum screen_cursor_style cstyle;
+       enum screen_cursor_style        cstyle;
+       int                             ccolour;
 
        /* Set cursor colour if changed. */
-       if (s != NULL && strcmp(s->ccolour, tty->ccolour) != 0)
-               tty_force_cursor_colour(tty, s->ccolour);
+       if (s != NULL) {
+               ccolour = s->ccolour;
+               if (s->ccolour == -1)
+                       ccolour = s->default_ccolour;
+               tty_force_cursor_colour(tty, ccolour);
+       }
 
        /* If cursor is off, set as invisible. */
        if (~mode & MODE_CURSOR) {