@@ -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 ;
@@ -1477,8 +1489,28 @@ term_get_cursor_shape(guicolor_T *fg, guicolor_T *bg)
14771489}
14781490#endif
14791491
1480- static int did_change_cursor = FALSE;
1492+ static void
1493+ may_output_cursor_props (void )
1494+ {
1495+ if (STRCMP (last_set_cursor_color , desired_cursor_color ) != 0
1496+ || last_set_cursor_shape != desired_cursor_shape
1497+ || last_set_cursor_blink != desired_cursor_blink )
1498+ {
1499+ last_set_cursor_color = desired_cursor_color ;
1500+ last_set_cursor_shape = desired_cursor_shape ;
1501+ last_set_cursor_blink = desired_cursor_blink ;
1502+ term_cursor_color (desired_cursor_color );
1503+ if (desired_cursor_shape == -1 || desired_cursor_blink == -1 )
1504+ /* this will restore the initial cursor style, if possible */
1505+ ui_cursor_shape_forced (TRUE);
1506+ else
1507+ term_cursor_shape (desired_cursor_shape , desired_cursor_blink );
1508+ }
1509+ }
14811510
1511+ /*
1512+ * Set the cursor color and shape, if not last set to these.
1513+ */
14821514 static void
14831515may_set_cursor_props (term_T * term )
14841516{
@@ -1490,29 +1522,30 @@ may_set_cursor_props(term_T *term)
14901522#endif
14911523 if (in_terminal_loop == term )
14921524 {
1493- did_change_cursor = TRUE;
14941525 if (term -> tl_cursor_color != NULL )
1495- term_cursor_color ( term -> tl_cursor_color ) ;
1526+ desired_cursor_color = term -> tl_cursor_color ;
14961527 else
1497- term_cursor_color ((char_u * )"" );
1498- term_cursor_shape (term -> tl_cursor_shape , term -> tl_cursor_blink );
1528+ desired_cursor_color = (char_u * )"" ;
1529+ desired_cursor_shape = term -> tl_cursor_shape ;
1530+ desired_cursor_blink = term -> tl_cursor_blink ;
1531+ may_output_cursor_props ();
14991532 }
15001533}
15011534
1535+ /*
1536+ * Reset the desired cursor properties and restore them when needed.
1537+ */
15021538 static void
1503- may_restore_cursor_props (void )
1539+ prepare_restore_cursor_props (void )
15041540{
15051541#ifdef FEAT_GUI
15061542 if (gui .in_use )
15071543 return ;
15081544#endif
1509- if (did_change_cursor )
1510- {
1511- did_change_cursor = FALSE;
1512- term_cursor_color ((char_u * )"" );
1513- /* this will restore the initial cursor style, if possible */
1514- ui_cursor_shape_forced (TRUE);
1515- }
1545+ desired_cursor_color = (char_u * )"" ;
1546+ desired_cursor_shape = -1 ;
1547+ desired_cursor_blink = -1 ;
1548+ may_output_cursor_props ();
15161549}
15171550
15181551/*
@@ -1549,6 +1582,7 @@ terminal_loop(int blocking)
15491582 int tty_fd = curbuf -> b_term -> tl_job -> jv_channel
15501583 -> ch_part [get_tty_part (curbuf -> b_term )].ch_fd ;
15511584#endif
1585+ int restore_cursor ;
15521586
15531587 /* Remember the terminal we are sending keys to. However, the terminal
15541588 * might be closed while waiting for a character, e.g. typing "exit" in a
@@ -1569,6 +1603,7 @@ terminal_loop(int blocking)
15691603 if (update_screen (0 ) == FAIL )
15701604 break ;
15711605 update_cursor (curbuf -> b_term , FALSE);
1606+ restore_cursor = TRUE;
15721607
15731608 c = term_vgetc ();
15741609 if (!term_use_loop ())
@@ -1677,6 +1712,11 @@ terminal_loop(int blocking)
16771712# endif
16781713 if (send_keys_to_term (curbuf -> b_term , c , TRUE) != OK )
16791714 {
1715+ if (c == K_MOUSEMOVE )
1716+ /* We are sure to come back here, don't reset the cursor color
1717+ * and shape to avoid flickering. */
1718+ restore_cursor = FALSE;
1719+
16801720 ret = OK ;
16811721 goto theend ;
16821722 }
@@ -1685,7 +1725,8 @@ terminal_loop(int blocking)
16851725
16861726theend :
16871727 in_terminal_loop = NULL ;
1688- may_restore_cursor_props ();
1728+ if (restore_cursor )
1729+ prepare_restore_cursor_props ();
16891730 return ret ;
16901731}
16911732
@@ -2010,6 +2051,8 @@ handle_settermprop(
20102051 break ;
20112052
20122053 case VTERM_PROP_CURSORCOLOR :
2054+ if (desired_cursor_color == term -> tl_cursor_color )
2055+ desired_cursor_color = (char_u * )"" ;
20132056 vim_free (term -> tl_cursor_color );
20142057 if (* value -> string == NUL )
20152058 term -> tl_cursor_color = NULL ;
@@ -3297,7 +3340,7 @@ term_send_eof(channel_T *ch)
32973340
32983341#define WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN 1ul
32993342#define WINPTY_SPAWN_FLAG_EXIT_AFTER_SHUTDOWN 2ull
3300- #define WINPTY_MOUSE_MODE_FORCE 2
3343+ #define WINPTY_MOUSE_MODE_FORCE 2
33013344
33023345void * (* winpty_config_new )(UINT64 , void * );
33033346void * (* winpty_open )(void * , void * );
0 commit comments