aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--input.c4
-rw-r--r--options-table.c12
-rw-r--r--options.c8
-rw-r--r--screen.c34
-rw-r--r--tmux.110
-rw-r--r--tmux.h5
-rw-r--r--tty.c54
7 files changed, 91 insertions, 36 deletions
diff --git a/input.c b/input.c
index b2769e31..3626c4b2 100644
--- a/input.c
+++ b/input.c
@@ -1619,7 +1619,7 @@ input_csi_dispatch(struct input_ctx *ictx)
case INPUT_CSI_DECSCUSR:
n = input_get(ictx, 0, 0, 0);
if (n != -1)
- screen_set_cursor_style(s, n);
+ screen_set_cursor_style(n, &s->cstyle, &s->mode);
break;
case INPUT_CSI_XDA:
n = input_get(ictx, 0, 0, 0);
@@ -1685,6 +1685,7 @@ input_csi_dispatch_rm_private(struct input_ctx *ictx)
break;
case 12:
screen_write_mode_clear(sctx, MODE_CURSOR_BLINKING);
+ screen_write_mode_set(sctx, MODE_CURSOR_BLINKING_SET);
break;
case 25: /* TCEM */
screen_write_mode_clear(sctx, MODE_CURSOR);
@@ -1774,6 +1775,7 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx)
break;
case 12:
screen_write_mode_set(sctx, MODE_CURSOR_BLINKING);
+ screen_write_mode_set(sctx, MODE_CURSOR_BLINKING_SET);
break;
case 25: /* TCEM */
screen_write_mode_set(sctx, MODE_CURSOR);
diff --git a/options-table.c b/options-table.c
index d23f7d57..bad22bfb 100644
--- a/options-table.c
+++ b/options-table.c
@@ -57,6 +57,10 @@ static const char *options_table_bell_action_list[] = {
static const char *options_table_visual_bell_list[] = {
"off", "on", "both", NULL
};
+static const char *options_table_cursor_style_list[] = {
+ "default", "blinking-block", "block", "blinking-underline", "underline",
+ "blinking-bar", "bar", NULL
+};
static const char *options_table_pane_status_list[] = {
"off", "top", "bottom", NULL
};
@@ -243,6 +247,14 @@ const struct options_table_entry options_table[] = {
.text = "Colour of the cursor."
},
+ { .name = "cursor-style",
+ .type = OPTIONS_TABLE_CHOICE,
+ .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
+ .choices = options_table_cursor_style_list,
+ .default_num = 0,
+ .text = "Style of the cursor."
+ },
+
{ .name = "default-terminal",
.type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_SERVER,
diff --git a/options.c b/options.c
index 4da1c408..865ab01f 100644
--- a/options.c
+++ b/options.c
@@ -1122,6 +1122,14 @@ options_push_changes(const char *name)
wp->screen->default_ccolour = c;
}
}
+ if (strcmp(name, "cursor-style") == 0) {
+ RB_FOREACH(wp, window_pane_tree, &all_window_panes) {
+ wp->screen->default_mode = 0;
+ screen_set_cursor_style(options_get_number(wp->options,
+ name), &wp->screen->default_cstyle,
+ &wp->screen->default_mode);
+ }
+ }
if (strcmp(name, "key-table") == 0) {
TAILQ_FOREACH(loop, &clients, entry)
server_client_set_key_table(loop, NULL);
diff --git a/screen.c b/screen.c
index bc95705a..da108866 100644
--- a/screen.c
+++ b/screen.c
@@ -82,6 +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->default_cstyle = SCREEN_CURSOR_DEFAULT;
+ s->default_mode = 0;
s->ccolour = -1;
s->default_ccolour = -1;
s->tabs = NULL;
@@ -152,38 +154,38 @@ screen_reset_tabs(struct screen *s)
bit_set(s->tabs, i);
}
-/* Set screen cursor style. */
+/* Set screen cursor style and mode. */
void
-screen_set_cursor_style(struct screen *s, u_int style)
+screen_set_cursor_style(u_int style, enum screen_cursor_style *cstyle,
+ int *mode)
{
- log_debug("%s: new %u, was %u", __func__, style, s->cstyle);
switch (style) {
case 0:
- s->cstyle = SCREEN_CURSOR_DEFAULT;
+ *cstyle = SCREEN_CURSOR_DEFAULT;
break;
case 1:
- s->cstyle = SCREEN_CURSOR_BLOCK;
- s->mode |= MODE_CURSOR_BLINKING;
+ *cstyle = SCREEN_CURSOR_BLOCK;
+ *mode |= MODE_CURSOR_BLINKING;
break;
case 2:
- s->cstyle = SCREEN_CURSOR_BLOCK;
- s->mode &= ~MODE_CURSOR_BLINKING;
+ *cstyle = SCREEN_CURSOR_BLOCK;
+ *mode &= ~MODE_CURSOR_BLINKING;
break;
case 3:
- s->cstyle = SCREEN_CURSOR_UNDERLINE;
- s->mode |= MODE_CURSOR_BLINKING;
+ *cstyle = SCREEN_CURSOR_UNDERLINE;
+ *mode |= MODE_CURSOR_BLINKING;
break;
case 4:
- s->cstyle = SCREEN_CURSOR_UNDERLINE;
- s->mode &= ~MODE_CURSOR_BLINKING;
+ *cstyle = SCREEN_CURSOR_UNDERLINE;
+ *mode &= ~MODE_CURSOR_BLINKING;
break;
case 5:
- s->cstyle = SCREEN_CURSOR_BAR;
- s->mode |= MODE_CURSOR_BLINKING;
+ *cstyle = SCREEN_CURSOR_BAR;
+ *mode |= MODE_CURSOR_BLINKING;
break;
case 6:
- s->cstyle = SCREEN_CURSOR_BAR;
- s->mode &= ~MODE_CURSOR_BLINKING;
+ *cstyle = SCREEN_CURSOR_BAR;
+ *mode &= ~MODE_CURSOR_BLINKING;
break;
}
}
diff --git a/tmux.1 b/tmux.1
index eb2340e3..4131719c 100644
--- a/tmux.1
+++ b/tmux.1
@@ -4426,6 +4426,16 @@ Each entry in the array defines the colour
uses when the colour with that index is requested.
The index may be from zero to 255.
.Pp
+.It Ic cursor-style Ar style
+Set the style of the cursor. Available styles are:
+.Ic default ,
+.Ic blinking-block ,
+.Ic block ,
+.Ic blinking-underline ,
+.Ic underline ,
+.Ic blinking-bar ,
+.Ic bar .
+.Pp
.It Xo Ic remain-on-exit
.Op Ic on | off | failed
.Xc
diff --git a/tmux.h b/tmux.h
index 62c84cc7..07e649f2 100644
--- a/tmux.h
+++ b/tmux.h
@@ -530,6 +530,7 @@ enum tty_code_code {
#define MODE_CRLF 0x4000
#define MODE_KEXTENDED 0x8000
#define MODE_CURSOR_VERY_VISIBLE 0x10000
+#define MODE_CURSOR_BLINKING_SET 0x20000
#define ALL_MODES 0xffffff
#define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ALL)
@@ -779,6 +780,7 @@ struct screen {
u_int cy; /* cursor y */
enum screen_cursor_style cstyle; /* cursor style */
+ enum screen_cursor_style default_cstyle;
int ccolour; /* cursor colour */
int default_ccolour;
@@ -786,6 +788,7 @@ struct screen {
u_int rlower; /* scroll region bottom */
int mode;
+ int default_mode;
u_int saved_cx;
u_int saved_cy;
@@ -2793,7 +2796,7 @@ void screen_init(struct screen *, u_int, u_int, u_int);
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_style(u_int, enum screen_cursor_style *, int *);
void screen_set_cursor_colour(struct screen *, int);
int screen_set_title(struct screen *, const char *);
void screen_set_path(struct screen *, const char *);
diff --git a/tty.c b/tty.c
index 38a7a752..70470a08 100644
--- a/tty.c
+++ b/tty.c
@@ -668,11 +668,11 @@ tty_force_cursor_colour(struct tty *tty, int c)
tty->ccolour = c;
}
-static void
-tty_update_cursor(struct tty *tty, int mode, int changed, struct screen *s)
+static int
+tty_update_cursor(struct tty *tty, int mode, struct screen *s)
{
enum screen_cursor_style cstyle;
- int ccolour;
+ int ccolour, changed, cmode = mode;
/* Set cursor colour if changed. */
if (s != NULL) {
@@ -683,19 +683,32 @@ tty_update_cursor(struct tty *tty, int mode, int changed, struct screen *s)
}
/* If cursor is off, set as invisible. */
- if (~mode & MODE_CURSOR) {
- if (changed & MODE_CURSOR)
+ if (~cmode & MODE_CURSOR) {
+ if (tty->mode & MODE_CURSOR)
tty_putcode(tty, TTYC_CIVIS);
- return;
+ return (cmode);
}
/* Check if blinking or very visible flag changed or style changed. */
if (s == NULL)
cstyle = tty->cstyle;
- else
+ else {
cstyle = s->cstyle;
+ if (cstyle == SCREEN_CURSOR_DEFAULT) {
+ if (~cmode & MODE_CURSOR_BLINKING_SET) {
+ if (s->default_mode & MODE_CURSOR_BLINKING)
+ cmode |= MODE_CURSOR_BLINKING;
+ else
+ cmode &= ~MODE_CURSOR_BLINKING;
+ }
+ cstyle = s->default_cstyle;
+ }
+ }
+
+ /* If nothing changed, do nothing. */
+ changed = cmode ^ tty->mode;
if ((changed & CURSOR_MODES) == 0 && cstyle == tty->cstyle)
- return;
+ return (cmode);
/*
* Set cursor style. If an explicit style has been set with DECSCUSR,
@@ -713,49 +726,56 @@ tty_update_cursor(struct tty *tty, int mode, int changed, struct screen *s)
else
tty_putcode1(tty, TTYC_SS, 0);
}
- if (mode & (MODE_CURSOR_BLINKING|MODE_CURSOR_VERY_VISIBLE))
+ if (cmode & (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)
+ if (cmode & MODE_CURSOR_BLINKING)
tty_putcode1(tty, TTYC_SS, 1);
else
tty_putcode1(tty, TTYC_SS, 2);
- } else if (mode & MODE_CURSOR_BLINKING)
+ } else if (cmode & 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)
+ if (cmode & MODE_CURSOR_BLINKING)
tty_putcode1(tty, TTYC_SS, 3);
else
tty_putcode1(tty, TTYC_SS, 4);
- } else if (mode & MODE_CURSOR_BLINKING)
+ } else if (cmode & 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)
+ if (cmode & MODE_CURSOR_BLINKING)
tty_putcode1(tty, TTYC_SS, 5);
else
tty_putcode1(tty, TTYC_SS, 6);
- } else if (mode & MODE_CURSOR_BLINKING)
+ } else if (cmode & MODE_CURSOR_BLINKING)
tty_putcode(tty, TTYC_CVVIS);
break;
}
tty->cstyle = cstyle;
+ return (cmode);
}
void
tty_update_mode(struct tty *tty, int mode, struct screen *s)
{
+ struct tty_term *term = tty->term;
struct client *c = tty->client;
int changed;
if (tty->flags & TTY_NOCURSOR)
mode &= ~MODE_CURSOR;
+ if (tty_update_cursor(tty, mode, s) & MODE_CURSOR_BLINKING)
+ mode |= MODE_CURSOR_BLINKING;
+ else
+ mode &= ~MODE_CURSOR_BLINKING;
+
changed = mode ^ tty->mode;
if (log_get_level() != 0 && changed != 0) {
log_debug("%s: current mode %s", c->name,
@@ -764,9 +784,7 @@ tty_update_mode(struct tty *tty, int mode, struct screen *s)
screen_mode_to_string(mode));
}
- tty_update_cursor(tty, mode, changed, s);
- if ((changed & ALL_MOUSE_MODES) &&
- tty_term_has(tty->term, TTYC_KMOUS)) {
+ if ((changed & ALL_MOUSE_MODES) && tty_term_has(term, TTYC_KMOUS)) {
/*
* If the mouse modes have changed, clear any that are set and
* apply again. There are differences in how terminals track