@@ -193,6 +193,16 @@ static int term_backspace_char = BS;
193193static int term_default_cterm_fg = -1 ;
194194static int term_default_cterm_bg = -1 ;
195195
196+ /* Store the last set and the desired cursor properties, so that we only update
197+ * them when needed. Doing it unnecessary may result in flicker. */
198+ static char_u * last_set_cursor_color = (char_u * )"" ;
199+ static char_u * desired_cursor_color = (char_u * )"" ;
200+ static int last_set_cursor_shape = -1 ;
201+ static int desired_cursor_shape = -1 ;
202+ static int last_set_cursor_blink = -1 ;
203+ static int desired_cursor_blink = -1 ;
204+
205+
196206/**************************************
197207 * 1. Generic code for all systems.
198208 */
@@ -630,7 +640,7 @@ free_terminal(buf_T *buf)
630640 {
631641 if (term -> tl_job -> jv_status != JOB_ENDED
632642 && term -> tl_job -> jv_status != JOB_FINISHED
633- && term -> tl_job -> jv_status != JOB_FAILED )
643+ && term -> tl_job -> jv_status != JOB_FAILED )
634644 job_stop (term -> tl_job , NULL , "kill" );
635645 job_unref (term -> tl_job );
636646 }
@@ -642,6 +652,8 @@ free_terminal(buf_T *buf)
642652 vim_free (term -> tl_status_text );
643653 vim_free (term -> tl_opencmd );
644654 vim_free (term -> tl_eof_chars );
655+ if (desired_cursor_color == term -> tl_cursor_color )
656+ desired_cursor_color = (char_u * )"" ;
645657 vim_free (term -> tl_cursor_color );
646658 vim_free (term );
647659 buf -> b_term = NULL ;
@@ -1472,8 +1484,28 @@ term_get_cursor_shape(guicolor_T *fg, guicolor_T *bg)
14721484}
14731485#endif
14741486
1475- static int did_change_cursor = FALSE;
1487+ static void
1488+ may_output_cursor_props (void )
1489+ {
1490+ if (STRCMP (last_set_cursor_color , desired_cursor_color ) != 0
1491+ || last_set_cursor_shape != desired_cursor_shape
1492+ || last_set_cursor_blink != desired_cursor_blink )
1493+ {
1494+ last_set_cursor_color = desired_cursor_color ;
1495+ last_set_cursor_shape = desired_cursor_shape ;
1496+ last_set_cursor_blink = desired_cursor_blink ;
1497+ term_cursor_color (desired_cursor_color );
1498+ if (desired_cursor_shape == -1 || desired_cursor_blink == -1 )
1499+ /* this will restore the initial cursor style, if possible */
1500+ ui_cursor_shape_forced (TRUE);
1501+ else
1502+ term_cursor_shape (desired_cursor_shape , desired_cursor_blink );
1503+ }
1504+ }
14761505
1506+ /*
1507+ * Set the cursor color and shape, if not last set to these.
1508+ */
14771509 static void
14781510may_set_cursor_props (term_T * term )
14791511{
@@ -1485,29 +1517,30 @@ may_set_cursor_props(term_T *term)
14851517#endif
14861518 if (in_terminal_loop == term )
14871519 {
1488- did_change_cursor = TRUE;
14891520 if (term -> tl_cursor_color != NULL )
1490- term_cursor_color ( term -> tl_cursor_color ) ;
1521+ desired_cursor_color = term -> tl_cursor_color ;
14911522 else
1492- term_cursor_color ((char_u * )"" );
1493- term_cursor_shape (term -> tl_cursor_shape , term -> tl_cursor_blink );
1523+ desired_cursor_color = (char_u * )"" ;
1524+ desired_cursor_shape = term -> tl_cursor_shape ;
1525+ desired_cursor_blink = term -> tl_cursor_blink ;
1526+ may_output_cursor_props ();
14941527 }
14951528}
14961529
1530+ /*
1531+ * Reset the desired cursor properties and restore them when needed.
1532+ */
14971533 static void
1498- may_restore_cursor_props (void )
1534+ prepare_restore_cursor_props (void )
14991535{
15001536#ifdef FEAT_GUI
15011537 if (gui .in_use )
15021538 return ;
15031539#endif
1504- if (did_change_cursor )
1505- {
1506- did_change_cursor = FALSE;
1507- term_cursor_color ((char_u * )"" );
1508- /* this will restore the initial cursor style, if possible */
1509- ui_cursor_shape_forced (TRUE);
1510- }
1540+ desired_cursor_color = (char_u * )"" ;
1541+ desired_cursor_shape = -1 ;
1542+ desired_cursor_blink = -1 ;
1543+ may_output_cursor_props ();
15111544}
15121545
15131546/*
@@ -1544,6 +1577,7 @@ terminal_loop(int blocking)
15441577 int tty_fd = curbuf -> b_term -> tl_job -> jv_channel
15451578 -> ch_part [get_tty_part (curbuf -> b_term )].ch_fd ;
15461579#endif
1580+ int restore_cursor ;
15471581
15481582 /* Remember the terminal we are sending keys to. However, the terminal
15491583 * might be closed while waiting for a character, e.g. typing "exit" in a
@@ -1564,6 +1598,7 @@ terminal_loop(int blocking)
15641598 if (update_screen (0 ) == FAIL )
15651599 break ;
15661600 update_cursor (curbuf -> b_term , FALSE);
1601+ restore_cursor = TRUE;
15671602
15681603 c = term_vgetc ();
15691604 if (!term_use_loop ())
@@ -1672,6 +1707,11 @@ terminal_loop(int blocking)
16721707# endif
16731708 if (send_keys_to_term (curbuf -> b_term , c , TRUE) != OK )
16741709 {
1710+ if (c == K_MOUSEMOVE )
1711+ /* We are sure to come back here, don't reset the cursor color
1712+ * and shape to avoid flickering. */
1713+ restore_cursor = FALSE;
1714+
16751715 ret = OK ;
16761716 goto theend ;
16771717 }
@@ -1680,7 +1720,8 @@ terminal_loop(int blocking)
16801720
16811721theend :
16821722 in_terminal_loop = NULL ;
1683- may_restore_cursor_props ();
1723+ if (restore_cursor )
1724+ prepare_restore_cursor_props ();
16841725 return ret ;
16851726}
16861727
@@ -2005,6 +2046,8 @@ handle_settermprop(
20052046 break ;
20062047
20072048 case VTERM_PROP_CURSORCOLOR :
2049+ if (desired_cursor_color == term -> tl_cursor_color )
2050+ desired_cursor_color = (char_u * )"" ;
20082051 vim_free (term -> tl_cursor_color );
20092052 if (* value -> string == NUL )
20102053 term -> tl_cursor_color = NULL ;
@@ -3292,7 +3335,7 @@ term_send_eof(channel_T *ch)
32923335
32933336#define WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN 1ul
32943337#define WINPTY_SPAWN_FLAG_EXIT_AFTER_SHUTDOWN 2ull
3295- #define WINPTY_MOUSE_MODE_FORCE 2
3338+ #define WINPTY_MOUSE_MODE_FORCE 2
32963339
32973340void * (* winpty_config_new )(UINT64 , void * );
32983341void * (* winpty_open )(void * , void * );
0 commit comments