Skip to content

Commit d317b38

Browse files
committed
patch 8.0.1477: redraw flicker when moving the mouse outside of terminal window
Problem: Redraw flicker when moving the mouse outside of terminal window. Solution: Instead of updating the cursor color and shape every time leaving and entering a terminal window, only update when different from the previously used cursor.
1 parent acda04f commit d317b38

2 files changed

Lines changed: 61 additions & 16 deletions

File tree

src/terminal.c

Lines changed: 59 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,16 @@ static int term_backspace_char = BS;
193193
static int term_default_cterm_fg = -1;
194194
static 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
14781510
may_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

16811721
theend:
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

32973340
void* (*winpty_config_new)(UINT64, void*);
32983341
void* (*winpty_open)(void*, void*);

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,8 @@ static char *(features[]) =
771771

772772
static int included_patches[] =
773773
{ /* Add new patch number below this line */
774+
/**/
775+
1477,
774776
/**/
775777
1476,
776778
/**/

0 commit comments

Comments
 (0)