mirror of
https://github.com/tmux/tmux.git
synced 2025-01-11 18:58:47 +00:00
Add a cursor-style option, from Alexis Hildebrandt in GitHub issue 2960.
This commit is contained in:
parent
200b6536e1
commit
57100376cc
4
input.c
4
input.c
@ -1619,7 +1619,7 @@ input_csi_dispatch(struct input_ctx *ictx)
|
|||||||
case INPUT_CSI_DECSCUSR:
|
case INPUT_CSI_DECSCUSR:
|
||||||
n = input_get(ictx, 0, 0, 0);
|
n = input_get(ictx, 0, 0, 0);
|
||||||
if (n != -1)
|
if (n != -1)
|
||||||
screen_set_cursor_style(s, n);
|
screen_set_cursor_style(n, &s->cstyle, &s->mode);
|
||||||
break;
|
break;
|
||||||
case INPUT_CSI_XDA:
|
case INPUT_CSI_XDA:
|
||||||
n = input_get(ictx, 0, 0, 0);
|
n = input_get(ictx, 0, 0, 0);
|
||||||
@ -1685,6 +1685,7 @@ input_csi_dispatch_rm_private(struct input_ctx *ictx)
|
|||||||
break;
|
break;
|
||||||
case 12:
|
case 12:
|
||||||
screen_write_mode_clear(sctx, MODE_CURSOR_BLINKING);
|
screen_write_mode_clear(sctx, MODE_CURSOR_BLINKING);
|
||||||
|
screen_write_mode_set(sctx, MODE_CURSOR_BLINKING_SET);
|
||||||
break;
|
break;
|
||||||
case 25: /* TCEM */
|
case 25: /* TCEM */
|
||||||
screen_write_mode_clear(sctx, MODE_CURSOR);
|
screen_write_mode_clear(sctx, MODE_CURSOR);
|
||||||
@ -1774,6 +1775,7 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx)
|
|||||||
break;
|
break;
|
||||||
case 12:
|
case 12:
|
||||||
screen_write_mode_set(sctx, MODE_CURSOR_BLINKING);
|
screen_write_mode_set(sctx, MODE_CURSOR_BLINKING);
|
||||||
|
screen_write_mode_set(sctx, MODE_CURSOR_BLINKING_SET);
|
||||||
break;
|
break;
|
||||||
case 25: /* TCEM */
|
case 25: /* TCEM */
|
||||||
screen_write_mode_set(sctx, MODE_CURSOR);
|
screen_write_mode_set(sctx, MODE_CURSOR);
|
||||||
|
@ -57,6 +57,10 @@ static const char *options_table_bell_action_list[] = {
|
|||||||
static const char *options_table_visual_bell_list[] = {
|
static const char *options_table_visual_bell_list[] = {
|
||||||
"off", "on", "both", NULL
|
"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[] = {
|
static const char *options_table_pane_status_list[] = {
|
||||||
"off", "top", "bottom", NULL
|
"off", "top", "bottom", NULL
|
||||||
};
|
};
|
||||||
@ -243,6 +247,14 @@ const struct options_table_entry options_table[] = {
|
|||||||
.text = "Colour of the cursor."
|
.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",
|
{ .name = "default-terminal",
|
||||||
.type = OPTIONS_TABLE_STRING,
|
.type = OPTIONS_TABLE_STRING,
|
||||||
.scope = OPTIONS_TABLE_SERVER,
|
.scope = OPTIONS_TABLE_SERVER,
|
||||||
|
@ -1122,6 +1122,14 @@ options_push_changes(const char *name)
|
|||||||
wp->screen->default_ccolour = c;
|
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) {
|
if (strcmp(name, "key-table") == 0) {
|
||||||
TAILQ_FOREACH(loop, &clients, entry)
|
TAILQ_FOREACH(loop, &clients, entry)
|
||||||
server_client_set_key_table(loop, NULL);
|
server_client_set_key_table(loop, NULL);
|
||||||
|
34
screen.c
34
screen.c
@ -82,6 +82,8 @@ screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit)
|
|||||||
s->path = NULL;
|
s->path = NULL;
|
||||||
|
|
||||||
s->cstyle = SCREEN_CURSOR_DEFAULT;
|
s->cstyle = SCREEN_CURSOR_DEFAULT;
|
||||||
|
s->default_cstyle = SCREEN_CURSOR_DEFAULT;
|
||||||
|
s->default_mode = 0;
|
||||||
s->ccolour = -1;
|
s->ccolour = -1;
|
||||||
s->default_ccolour = -1;
|
s->default_ccolour = -1;
|
||||||
s->tabs = NULL;
|
s->tabs = NULL;
|
||||||
@ -152,38 +154,38 @@ screen_reset_tabs(struct screen *s)
|
|||||||
bit_set(s->tabs, i);
|
bit_set(s->tabs, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set screen cursor style. */
|
/* Set screen cursor style and mode. */
|
||||||
void
|
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) {
|
switch (style) {
|
||||||
case 0:
|
case 0:
|
||||||
s->cstyle = SCREEN_CURSOR_DEFAULT;
|
*cstyle = SCREEN_CURSOR_DEFAULT;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
s->cstyle = SCREEN_CURSOR_BLOCK;
|
*cstyle = SCREEN_CURSOR_BLOCK;
|
||||||
s->mode |= MODE_CURSOR_BLINKING;
|
*mode |= MODE_CURSOR_BLINKING;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
s->cstyle = SCREEN_CURSOR_BLOCK;
|
*cstyle = SCREEN_CURSOR_BLOCK;
|
||||||
s->mode &= ~MODE_CURSOR_BLINKING;
|
*mode &= ~MODE_CURSOR_BLINKING;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
s->cstyle = SCREEN_CURSOR_UNDERLINE;
|
*cstyle = SCREEN_CURSOR_UNDERLINE;
|
||||||
s->mode |= MODE_CURSOR_BLINKING;
|
*mode |= MODE_CURSOR_BLINKING;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
s->cstyle = SCREEN_CURSOR_UNDERLINE;
|
*cstyle = SCREEN_CURSOR_UNDERLINE;
|
||||||
s->mode &= ~MODE_CURSOR_BLINKING;
|
*mode &= ~MODE_CURSOR_BLINKING;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
s->cstyle = SCREEN_CURSOR_BAR;
|
*cstyle = SCREEN_CURSOR_BAR;
|
||||||
s->mode |= MODE_CURSOR_BLINKING;
|
*mode |= MODE_CURSOR_BLINKING;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
s->cstyle = SCREEN_CURSOR_BAR;
|
*cstyle = SCREEN_CURSOR_BAR;
|
||||||
s->mode &= ~MODE_CURSOR_BLINKING;
|
*mode &= ~MODE_CURSOR_BLINKING;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
tmux.1
10
tmux.1
@ -4426,6 +4426,16 @@ Each entry in the array defines the colour
|
|||||||
uses when the colour with that index is requested.
|
uses when the colour with that index is requested.
|
||||||
The index may be from zero to 255.
|
The index may be from zero to 255.
|
||||||
.Pp
|
.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
|
.It Xo Ic remain-on-exit
|
||||||
.Op Ic on | off | failed
|
.Op Ic on | off | failed
|
||||||
.Xc
|
.Xc
|
||||||
|
5
tmux.h
5
tmux.h
@ -530,6 +530,7 @@ enum tty_code_code {
|
|||||||
#define MODE_CRLF 0x4000
|
#define MODE_CRLF 0x4000
|
||||||
#define MODE_KEXTENDED 0x8000
|
#define MODE_KEXTENDED 0x8000
|
||||||
#define MODE_CURSOR_VERY_VISIBLE 0x10000
|
#define MODE_CURSOR_VERY_VISIBLE 0x10000
|
||||||
|
#define MODE_CURSOR_BLINKING_SET 0x20000
|
||||||
|
|
||||||
#define ALL_MODES 0xffffff
|
#define ALL_MODES 0xffffff
|
||||||
#define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ALL)
|
#define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ALL)
|
||||||
@ -779,6 +780,7 @@ struct screen {
|
|||||||
u_int cy; /* cursor y */
|
u_int cy; /* cursor y */
|
||||||
|
|
||||||
enum screen_cursor_style cstyle; /* cursor style */
|
enum screen_cursor_style cstyle; /* cursor style */
|
||||||
|
enum screen_cursor_style default_cstyle;
|
||||||
int ccolour; /* cursor colour */
|
int ccolour; /* cursor colour */
|
||||||
int default_ccolour;
|
int default_ccolour;
|
||||||
|
|
||||||
@ -786,6 +788,7 @@ struct screen {
|
|||||||
u_int rlower; /* scroll region bottom */
|
u_int rlower; /* scroll region bottom */
|
||||||
|
|
||||||
int mode;
|
int mode;
|
||||||
|
int default_mode;
|
||||||
|
|
||||||
u_int saved_cx;
|
u_int saved_cx;
|
||||||
u_int saved_cy;
|
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_reinit(struct screen *);
|
||||||
void screen_free(struct screen *);
|
void screen_free(struct screen *);
|
||||||
void screen_reset_tabs(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);
|
void screen_set_cursor_colour(struct screen *, int);
|
||||||
int screen_set_title(struct screen *, const char *);
|
int screen_set_title(struct screen *, const char *);
|
||||||
void screen_set_path(struct screen *, const char *);
|
void screen_set_path(struct screen *, const char *);
|
||||||
|
54
tty.c
54
tty.c
@ -668,11 +668,11 @@ tty_force_cursor_colour(struct tty *tty, int c)
|
|||||||
tty->ccolour = c;
|
tty->ccolour = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
tty_update_cursor(struct tty *tty, int mode, int changed, struct screen *s)
|
tty_update_cursor(struct tty *tty, int mode, struct screen *s)
|
||||||
{
|
{
|
||||||
enum screen_cursor_style cstyle;
|
enum screen_cursor_style cstyle;
|
||||||
int ccolour;
|
int ccolour, changed, cmode = mode;
|
||||||
|
|
||||||
/* Set cursor colour if changed. */
|
/* Set cursor colour if changed. */
|
||||||
if (s != NULL) {
|
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 cursor is off, set as invisible. */
|
||||||
if (~mode & MODE_CURSOR) {
|
if (~cmode & MODE_CURSOR) {
|
||||||
if (changed & MODE_CURSOR)
|
if (tty->mode & MODE_CURSOR)
|
||||||
tty_putcode(tty, TTYC_CIVIS);
|
tty_putcode(tty, TTYC_CIVIS);
|
||||||
return;
|
return (cmode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if blinking or very visible flag changed or style changed. */
|
/* Check if blinking or very visible flag changed or style changed. */
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
cstyle = tty->cstyle;
|
cstyle = tty->cstyle;
|
||||||
else
|
else {
|
||||||
cstyle = s->cstyle;
|
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)
|
if ((changed & CURSOR_MODES) == 0 && cstyle == tty->cstyle)
|
||||||
return;
|
return (cmode);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set cursor style. If an explicit style has been set with DECSCUSR,
|
* 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
|
else
|
||||||
tty_putcode1(tty, TTYC_SS, 0);
|
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);
|
tty_putcode(tty, TTYC_CVVIS);
|
||||||
break;
|
break;
|
||||||
case SCREEN_CURSOR_BLOCK:
|
case SCREEN_CURSOR_BLOCK:
|
||||||
if (tty_term_has(tty->term, TTYC_SS)) {
|
if (tty_term_has(tty->term, TTYC_SS)) {
|
||||||
if (mode & MODE_CURSOR_BLINKING)
|
if (cmode & MODE_CURSOR_BLINKING)
|
||||||
tty_putcode1(tty, TTYC_SS, 1);
|
tty_putcode1(tty, TTYC_SS, 1);
|
||||||
else
|
else
|
||||||
tty_putcode1(tty, TTYC_SS, 2);
|
tty_putcode1(tty, TTYC_SS, 2);
|
||||||
} else if (mode & MODE_CURSOR_BLINKING)
|
} else if (cmode & MODE_CURSOR_BLINKING)
|
||||||
tty_putcode(tty, TTYC_CVVIS);
|
tty_putcode(tty, TTYC_CVVIS);
|
||||||
break;
|
break;
|
||||||
case SCREEN_CURSOR_UNDERLINE:
|
case SCREEN_CURSOR_UNDERLINE:
|
||||||
if (tty_term_has(tty->term, TTYC_SS)) {
|
if (tty_term_has(tty->term, TTYC_SS)) {
|
||||||
if (mode & MODE_CURSOR_BLINKING)
|
if (cmode & MODE_CURSOR_BLINKING)
|
||||||
tty_putcode1(tty, TTYC_SS, 3);
|
tty_putcode1(tty, TTYC_SS, 3);
|
||||||
else
|
else
|
||||||
tty_putcode1(tty, TTYC_SS, 4);
|
tty_putcode1(tty, TTYC_SS, 4);
|
||||||
} else if (mode & MODE_CURSOR_BLINKING)
|
} else if (cmode & MODE_CURSOR_BLINKING)
|
||||||
tty_putcode(tty, TTYC_CVVIS);
|
tty_putcode(tty, TTYC_CVVIS);
|
||||||
break;
|
break;
|
||||||
case SCREEN_CURSOR_BAR:
|
case SCREEN_CURSOR_BAR:
|
||||||
if (tty_term_has(tty->term, TTYC_SS)) {
|
if (tty_term_has(tty->term, TTYC_SS)) {
|
||||||
if (mode & MODE_CURSOR_BLINKING)
|
if (cmode & MODE_CURSOR_BLINKING)
|
||||||
tty_putcode1(tty, TTYC_SS, 5);
|
tty_putcode1(tty, TTYC_SS, 5);
|
||||||
else
|
else
|
||||||
tty_putcode1(tty, TTYC_SS, 6);
|
tty_putcode1(tty, TTYC_SS, 6);
|
||||||
} else if (mode & MODE_CURSOR_BLINKING)
|
} else if (cmode & MODE_CURSOR_BLINKING)
|
||||||
tty_putcode(tty, TTYC_CVVIS);
|
tty_putcode(tty, TTYC_CVVIS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tty->cstyle = cstyle;
|
tty->cstyle = cstyle;
|
||||||
|
return (cmode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tty_update_mode(struct tty *tty, int mode, struct screen *s)
|
tty_update_mode(struct tty *tty, int mode, struct screen *s)
|
||||||
{
|
{
|
||||||
|
struct tty_term *term = tty->term;
|
||||||
struct client *c = tty->client;
|
struct client *c = tty->client;
|
||||||
int changed;
|
int changed;
|
||||||
|
|
||||||
if (tty->flags & TTY_NOCURSOR)
|
if (tty->flags & TTY_NOCURSOR)
|
||||||
mode &= ~MODE_CURSOR;
|
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;
|
changed = mode ^ tty->mode;
|
||||||
if (log_get_level() != 0 && changed != 0) {
|
if (log_get_level() != 0 && changed != 0) {
|
||||||
log_debug("%s: current mode %s", c->name,
|
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));
|
screen_mode_to_string(mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
tty_update_cursor(tty, mode, changed, s);
|
if ((changed & ALL_MOUSE_MODES) && tty_term_has(term, TTYC_KMOUS)) {
|
||||||
if ((changed & ALL_MOUSE_MODES) &&
|
|
||||||
tty_term_has(tty->term, TTYC_KMOUS)) {
|
|
||||||
/*
|
/*
|
||||||
* If the mouse modes have changed, clear any that are set and
|
* If the mouse modes have changed, clear any that are set and
|
||||||
* apply again. There are differences in how terminals track
|
* apply again. There are differences in how terminals track
|
||||||
|
Loading…
Reference in New Issue
Block a user