mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:26:05 +00:00 
			
		
		
		
	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.
This commit is contained in:
		
							
								
								
									
										32
									
								
								screen.c
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								screen.c
									
									
									
									
									
								
							@@ -80,7 +80,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;
 | 
			
		||||
@@ -155,9 +155,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;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								tmux.h
									
									
									
									
									
								
							@@ -795,6 +795,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;
 | 
			
		||||
@@ -808,8 +816,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 */
 | 
			
		||||
@@ -1297,7 +1305,7 @@ struct tty {
 | 
			
		||||
 | 
			
		||||
	u_int		 cx;
 | 
			
		||||
	u_int		 cy;
 | 
			
		||||
	u_int		 cstyle;
 | 
			
		||||
	enum screen_cursor_style cstyle;
 | 
			
		||||
	char		*ccolour;
 | 
			
		||||
 | 
			
		||||
	int		 oflag;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										117
									
								
								tty.c
									
									
									
									
									
								
							
							
						
						
									
										117
									
								
								tty.c
									
									
									
									
									
								
							@@ -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) &&
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user