forked from aniani/vim
patch 8.0.1009: Xterm cursor blinking status may be inverted
Problem: Xterm cursor blinking status may be inverted. Solution: Use another request to get the blink status and compare with the cursor style report
This commit is contained in:
@@ -3194,6 +3194,7 @@ static struct vimoption options[] =
|
|||||||
p_term("t_nd", T_ND)
|
p_term("t_nd", T_ND)
|
||||||
p_term("t_op", T_OP)
|
p_term("t_op", T_OP)
|
||||||
p_term("t_RB", T_RBG)
|
p_term("t_RB", T_RBG)
|
||||||
|
p_term("t_RC", T_CRC)
|
||||||
p_term("t_RI", T_CRI)
|
p_term("t_RI", T_CRI)
|
||||||
p_term("t_RS", T_CRS)
|
p_term("t_RS", T_CRS)
|
||||||
p_term("t_RV", T_CRV)
|
p_term("t_RV", T_CRV)
|
||||||
|
@@ -53,6 +53,7 @@ void cursor_on(void);
|
|||||||
void cursor_off(void);
|
void cursor_off(void);
|
||||||
void term_cursor_mode(int forced);
|
void term_cursor_mode(int forced);
|
||||||
void term_cursor_color(char_u *color);
|
void term_cursor_color(char_u *color);
|
||||||
|
int blink_state_is_inverted(void);
|
||||||
void term_cursor_shape(int shape, int blink);
|
void term_cursor_shape(int shape, int blink);
|
||||||
void scroll_region_set(win_T *wp, int off);
|
void scroll_region_set(win_T *wp, int off);
|
||||||
void scroll_region_reset(void);
|
void scroll_region_reset(void);
|
||||||
|
107
src/term.c
107
src/term.c
@@ -128,8 +128,11 @@ static int u7_status = STATUS_GET;
|
|||||||
/* Request background color report: */
|
/* Request background color report: */
|
||||||
static int rbg_status = STATUS_GET;
|
static int rbg_status = STATUS_GET;
|
||||||
|
|
||||||
/* Request cursor mode report: */
|
/* Request cursor blinking mode report: */
|
||||||
static int rcm_status = STATUS_GET;
|
static int rbm_status = STATUS_GET;
|
||||||
|
|
||||||
|
/* Request cursor style report: */
|
||||||
|
static int rcs_status = STATUS_GET;
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -163,9 +166,14 @@ static int detected_8bit = FALSE; /* detected 8-bit terminal */
|
|||||||
|
|
||||||
#ifdef FEAT_TERMRESPONSE
|
#ifdef FEAT_TERMRESPONSE
|
||||||
/* When the cursor shape was detected these values are used:
|
/* When the cursor shape was detected these values are used:
|
||||||
* 1: block, 2: underline, 3: vertical bar
|
* 1: block, 2: underline, 3: vertical bar */
|
||||||
* initial_cursor_blink is only valid when initial_cursor_shape is not zero. */
|
|
||||||
static int initial_cursor_shape = 0;
|
static int initial_cursor_shape = 0;
|
||||||
|
|
||||||
|
/* The blink flag from the style response may be inverted from the actual
|
||||||
|
* blinking state, xterm XORs the flags. */
|
||||||
|
static int initial_cursor_shape_blink = FALSE;
|
||||||
|
|
||||||
|
/* The blink flag from the blinking-cursor mode response */
|
||||||
static int initial_cursor_blink = FALSE;
|
static int initial_cursor_blink = FALSE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -835,6 +843,7 @@ static struct builtin_term builtin_termcaps[] =
|
|||||||
# else
|
# else
|
||||||
{(int)KS_CSH, IF_EB("\033[%d q", ESC_STR "[%d q")},
|
{(int)KS_CSH, IF_EB("\033[%d q", ESC_STR "[%d q")},
|
||||||
# endif
|
# endif
|
||||||
|
{(int)KS_CRC, IF_EB("\033[?12$p", ESC_STR "[?12$p")},
|
||||||
{(int)KS_CRS, IF_EB("\033P$q q\033\\", ESC_STR "P$q q" ESC_STR "\\")},
|
{(int)KS_CRS, IF_EB("\033P$q q\033\\", ESC_STR "P$q q" ESC_STR "\\")},
|
||||||
# ifdef TERMINFO
|
# ifdef TERMINFO
|
||||||
{(int)KS_CM, IF_EB("\033[%i%p1%d;%p2%dH",
|
{(int)KS_CM, IF_EB("\033[%i%p1%d;%p2%dH",
|
||||||
@@ -3316,7 +3325,8 @@ settmode(int tmode)
|
|||||||
if (tmode != TMODE_RAW && (crv_status == STATUS_SENT
|
if (tmode != TMODE_RAW && (crv_status == STATUS_SENT
|
||||||
|| u7_status == STATUS_SENT
|
|| u7_status == STATUS_SENT
|
||||||
|| rbg_status == STATUS_SENT
|
|| rbg_status == STATUS_SENT
|
||||||
|| rcm_status == STATUS_SENT))
|
|| rbm_status == STATUS_SENT
|
||||||
|
|| rcs_status == STATUS_SENT))
|
||||||
(void)vpeekc_nomap();
|
(void)vpeekc_nomap();
|
||||||
check_for_codes_from_term();
|
check_for_codes_from_term();
|
||||||
}
|
}
|
||||||
@@ -3386,7 +3396,8 @@ stoptermcap(void)
|
|||||||
if (crv_status == STATUS_SENT
|
if (crv_status == STATUS_SENT
|
||||||
|| u7_status == STATUS_SENT
|
|| u7_status == STATUS_SENT
|
||||||
|| rbg_status == STATUS_SENT
|
|| rbg_status == STATUS_SENT
|
||||||
|| rcm_status == STATUS_SENT)
|
|| rbm_status == STATUS_SENT
|
||||||
|
|| rcs_status == STATUS_SENT)
|
||||||
{
|
{
|
||||||
# ifdef UNIX
|
# ifdef UNIX
|
||||||
/* Give the terminal a chance to respond. */
|
/* Give the terminal a chance to respond. */
|
||||||
@@ -3500,6 +3511,8 @@ may_req_ambiguous_char_width(void)
|
|||||||
void
|
void
|
||||||
may_req_bg_color(void)
|
may_req_bg_color(void)
|
||||||
{
|
{
|
||||||
|
int did_one = FALSE;
|
||||||
|
|
||||||
if (can_get_termresponse() && starting == 0)
|
if (can_get_termresponse() && starting == 0)
|
||||||
{
|
{
|
||||||
/* Only request background if t_RB is set and 'background' wasn't
|
/* Only request background if t_RB is set and 'background' wasn't
|
||||||
@@ -3511,7 +3524,20 @@ may_req_bg_color(void)
|
|||||||
LOG_TR("Sending BG request");
|
LOG_TR("Sending BG request");
|
||||||
out_str(T_RBG);
|
out_str(T_RBG);
|
||||||
rbg_status = STATUS_SENT;
|
rbg_status = STATUS_SENT;
|
||||||
|
did_one = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only request cursor blinking mode if t_RC is set. */
|
||||||
|
if (rbm_status == STATUS_GET && *T_CRC != NUL)
|
||||||
|
{
|
||||||
|
LOG_TR("Sending BC request");
|
||||||
|
out_str(T_CRC);
|
||||||
|
rbm_status = STATUS_SENT;
|
||||||
|
did_one = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (did_one)
|
||||||
|
{
|
||||||
/* check for the characters now, otherwise they might be eaten by
|
/* check for the characters now, otherwise they might be eaten by
|
||||||
* get_keystroke() */
|
* get_keystroke() */
|
||||||
out_flush();
|
out_flush();
|
||||||
@@ -3751,6 +3777,13 @@ term_cursor_color(char_u *color)
|
|||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
int
|
||||||
|
blink_state_is_inverted()
|
||||||
|
{
|
||||||
|
return rbm_status == STATUS_GOT && rcs_status == STATUS_GOT
|
||||||
|
&& initial_cursor_blink != initial_cursor_shape_blink;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "shape": 1 = block, 2 = underline, 3 = vertical bar
|
* "shape": 1 = block, 2 = underline, 3 = vertical bar
|
||||||
*/
|
*/
|
||||||
@@ -3762,16 +3795,26 @@ term_cursor_shape(int shape, int blink)
|
|||||||
OUT_STR(tgoto((char *)T_CSH, 0, shape * 2 - blink));
|
OUT_STR(tgoto((char *)T_CSH, 0, shape * 2 - blink));
|
||||||
out_flush();
|
out_flush();
|
||||||
}
|
}
|
||||||
/* When t_SH is not set try setting just the blink state. */
|
else
|
||||||
else if (blink && *T_VS != NUL)
|
|
||||||
{
|
{
|
||||||
out_str(T_VS);
|
int do_blink = blink;
|
||||||
out_flush();
|
|
||||||
}
|
/* t_SH is empty: try setting just the blink state.
|
||||||
else if (!blink && *T_CVS != NUL)
|
* The blink flags are XORed together, if the initial blinking from
|
||||||
{
|
* style and shape differs, we need to invert the flag here. */
|
||||||
out_str(T_CVS);
|
if (blink_state_is_inverted())
|
||||||
out_flush();
|
do_blink = !blink;
|
||||||
|
|
||||||
|
if (do_blink && *T_VS != NUL)
|
||||||
|
{
|
||||||
|
out_str(T_VS);
|
||||||
|
out_flush();
|
||||||
|
}
|
||||||
|
else if (!do_blink && *T_CVS != NUL)
|
||||||
|
{
|
||||||
|
out_str(T_CVS);
|
||||||
|
out_flush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -4533,7 +4576,7 @@ check_termcode(
|
|||||||
/* Only request the cursor style if t_SH and t_RS are
|
/* Only request the cursor style if t_SH and t_RS are
|
||||||
* set. Not for Terminal.app, it can't handle t_RS, it
|
* set. Not for Terminal.app, it can't handle t_RS, it
|
||||||
* echoes the characters to the screen. */
|
* echoes the characters to the screen. */
|
||||||
if (rcm_status == STATUS_GET
|
if (rcs_status == STATUS_GET
|
||||||
# ifdef MACOS
|
# ifdef MACOS
|
||||||
&& !is_terminal_app
|
&& !is_terminal_app
|
||||||
# endif
|
# endif
|
||||||
@@ -4542,7 +4585,7 @@ check_termcode(
|
|||||||
{
|
{
|
||||||
LOG_TR("Sending cursor style request");
|
LOG_TR("Sending cursor style request");
|
||||||
out_str(T_CRS);
|
out_str(T_CRS);
|
||||||
rcm_status = STATUS_SENT;
|
rcs_status = STATUS_SENT;
|
||||||
out_flush();
|
out_flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4558,6 +4601,29 @@ check_termcode(
|
|||||||
slen = i + 1;
|
slen = i + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check blinking cursor from xterm:
|
||||||
|
* {lead}?12;1$y set
|
||||||
|
* {lead}?12;2$y not set
|
||||||
|
*
|
||||||
|
* {lead} can be <Esc>[ or CSI
|
||||||
|
*/
|
||||||
|
else if (rbm_status == STATUS_SENT
|
||||||
|
&& tp[(j = 1 + (tp[0] == ESC))] == '?'
|
||||||
|
&& i == j + 6
|
||||||
|
&& tp[j + 1] == '1'
|
||||||
|
&& tp[j + 2] == '2'
|
||||||
|
&& tp[j + 3] == ';'
|
||||||
|
&& tp[i - 1] == '$'
|
||||||
|
&& tp[i] == 'y')
|
||||||
|
{
|
||||||
|
initial_cursor_blink = (tp[j + 4] == '1');
|
||||||
|
rbm_status = STATUS_GOT;
|
||||||
|
LOG_TR("Received cursor blinking mode response");
|
||||||
|
key_name[0] = (int)KS_EXTRA;
|
||||||
|
key_name[1] = (int)KE_IGNORE;
|
||||||
|
slen = i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for a window position response from the terminal:
|
* Check for a window position response from the terminal:
|
||||||
* {lead}3;{x}:{y}t
|
* {lead}3;{x}:{y}t
|
||||||
@@ -4668,7 +4734,7 @@ check_termcode(
|
|||||||
*
|
*
|
||||||
* Consume any code that starts with "{lead}.+r" or "{lead}.$r".
|
* Consume any code that starts with "{lead}.+r" or "{lead}.$r".
|
||||||
*/
|
*/
|
||||||
else if ((check_for_codes || rcm_status == STATUS_SENT)
|
else if ((check_for_codes || rcs_status == STATUS_SENT)
|
||||||
&& ((tp[0] == ESC && len >= 2 && tp[1] == 'P')
|
&& ((tp[0] == ESC && len >= 2 && tp[1] == 'P')
|
||||||
|| tp[0] == DCS))
|
|| tp[0] == DCS))
|
||||||
{
|
{
|
||||||
@@ -4710,8 +4776,9 @@ check_termcode(
|
|||||||
initial_cursor_shape = (number + 1) / 2;
|
initial_cursor_shape = (number + 1) / 2;
|
||||||
/* The blink flag is actually inverted, compared to
|
/* The blink flag is actually inverted, compared to
|
||||||
* the value set with T_SH. */
|
* the value set with T_SH. */
|
||||||
initial_cursor_blink = (number & 1) ? FALSE : TRUE;
|
initial_cursor_shape_blink =
|
||||||
rcm_status = STATUS_GOT;
|
(number & 1) ? FALSE : TRUE;
|
||||||
|
rcs_status = STATUS_GOT;
|
||||||
LOG_TR("Received cursor shape response");
|
LOG_TR("Received cursor shape response");
|
||||||
|
|
||||||
key_name[0] = (int)KS_EXTRA;
|
key_name[0] = (int)KS_EXTRA;
|
||||||
|
@@ -42,7 +42,8 @@ enum SpecialKey
|
|||||||
KS_VS, /* cursor very visible (blink) */
|
KS_VS, /* cursor very visible (blink) */
|
||||||
KS_CVS, /* cursor normally visible (no blink) */
|
KS_CVS, /* cursor normally visible (no blink) */
|
||||||
KS_CSH, /* cursor shape */
|
KS_CSH, /* cursor shape */
|
||||||
KS_CRS, /* request cursor shape */
|
KS_CRC, /* request cursor blinking */
|
||||||
|
KS_CRS, /* request cursor style */
|
||||||
KS_ME, /* normal mode */
|
KS_ME, /* normal mode */
|
||||||
KS_MR, /* reverse mode */
|
KS_MR, /* reverse mode */
|
||||||
KS_MD, /* bold mode */
|
KS_MD, /* bold mode */
|
||||||
@@ -135,7 +136,8 @@ extern char_u *(term_strings[]); /* current terminal strings */
|
|||||||
#define T_VS (TERM_STR(KS_VS)) /* cursor very visible (blink) */
|
#define T_VS (TERM_STR(KS_VS)) /* cursor very visible (blink) */
|
||||||
#define T_CVS (TERM_STR(KS_CVS)) /* cursor normally visible (no blink) */
|
#define T_CVS (TERM_STR(KS_CVS)) /* cursor normally visible (no blink) */
|
||||||
#define T_CSH (TERM_STR(KS_CSH)) /* cursor shape */
|
#define T_CSH (TERM_STR(KS_CSH)) /* cursor shape */
|
||||||
#define T_CRS (TERM_STR(KS_CRS)) /* request cursor shape */
|
#define T_CRC (TERM_STR(KS_CRC)) /* request cursor blinking */
|
||||||
|
#define T_CRS (TERM_STR(KS_CRS)) /* request cursor style */
|
||||||
#define T_ME (TERM_STR(KS_ME)) /* normal mode */
|
#define T_ME (TERM_STR(KS_ME)) /* normal mode */
|
||||||
#define T_MR (TERM_STR(KS_MR)) /* reverse mode */
|
#define T_MR (TERM_STR(KS_MR)) /* reverse mode */
|
||||||
#define T_MD (TERM_STR(KS_MD)) /* bold mode */
|
#define T_MD (TERM_STR(KS_MD)) /* bold mode */
|
||||||
|
@@ -39,7 +39,6 @@
|
|||||||
*
|
*
|
||||||
* TODO:
|
* TODO:
|
||||||
* - ":term NONE" does not work in MS-Windows.
|
* - ":term NONE" does not work in MS-Windows.
|
||||||
* - better check for blinking - reply from Thomas Dickey Aug 22
|
|
||||||
* - test for writing lines to terminal job does not work on MS-Windows
|
* - test for writing lines to terminal job does not work on MS-Windows
|
||||||
* - implement term_setsize()
|
* - implement term_setsize()
|
||||||
* - add test for giving error for invalid 'termsize' value.
|
* - add test for giving error for invalid 'termsize' value.
|
||||||
@@ -2482,7 +2481,8 @@ f_term_getcursor(typval_T *argvars, typval_T *rettv)
|
|||||||
if (d != NULL)
|
if (d != NULL)
|
||||||
{
|
{
|
||||||
dict_add_nr_str(d, "visible", term->tl_cursor_visible, NULL);
|
dict_add_nr_str(d, "visible", term->tl_cursor_visible, NULL);
|
||||||
dict_add_nr_str(d, "blink", term->tl_cursor_blink, NULL);
|
dict_add_nr_str(d, "blink", blink_state_is_inverted()
|
||||||
|
? !term->tl_cursor_blink : term->tl_cursor_blink, NULL);
|
||||||
dict_add_nr_str(d, "shape", term->tl_cursor_shape, NULL);
|
dict_add_nr_str(d, "shape", term->tl_cursor_shape, NULL);
|
||||||
dict_add_nr_str(d, "color", 0L, term->tl_cursor_color == NULL
|
dict_add_nr_str(d, "color", 0L, term->tl_cursor_color == NULL
|
||||||
? (char_u *)"" : term->tl_cursor_color);
|
? (char_u *)"" : term->tl_cursor_color);
|
||||||
|
@@ -769,6 +769,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1009,
|
||||||
/**/
|
/**/
|
||||||
1008,
|
1008,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user