comparison src/terminal.c @ 13206:53f0c469dfc6 v8.0.1477

patch 8.0.1477: redraw flicker when moving the mouse outside of terminal window commit https://github.com/vim/vim/commit/d317b38a4dbcdbd4cf587cf78cc1f4289374214e Author: Bram Moolenaar <Bram@vim.org> Date: Thu Feb 8 22:33:31 2018 +0100 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.
author Christian Brabandt <cb@256bit.org>
date Thu, 08 Feb 2018 22:45:05 +0100
parents fe0cec169589
children 4b8d89ea9edb
comparison
equal deleted inserted replaced
13205:fb5de9f2a96a 13206:53f0c469dfc6
191 191
192 /* "Terminal" highlight group colors. */ 192 /* "Terminal" highlight group colors. */
193 static int term_default_cterm_fg = -1; 193 static int term_default_cterm_fg = -1;
194 static int term_default_cterm_bg = -1; 194 static int term_default_cterm_bg = -1;
195 195
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
196 /************************************** 206 /**************************************
197 * 1. Generic code for all systems. 207 * 1. Generic code for all systems.
198 */ 208 */
199 209
200 /* 210 /*
628 638
629 if (term->tl_job != NULL) 639 if (term->tl_job != NULL)
630 { 640 {
631 if (term->tl_job->jv_status != JOB_ENDED 641 if (term->tl_job->jv_status != JOB_ENDED
632 && term->tl_job->jv_status != JOB_FINISHED 642 && term->tl_job->jv_status != JOB_FINISHED
633 && term->tl_job->jv_status != JOB_FAILED) 643 && term->tl_job->jv_status != JOB_FAILED)
634 job_stop(term->tl_job, NULL, "kill"); 644 job_stop(term->tl_job, NULL, "kill");
635 job_unref(term->tl_job); 645 job_unref(term->tl_job);
636 } 646 }
637 647
638 free_scrollback(term); 648 free_scrollback(term);
640 term_free_vterm(term); 650 term_free_vterm(term);
641 vim_free(term->tl_title); 651 vim_free(term->tl_title);
642 vim_free(term->tl_status_text); 652 vim_free(term->tl_status_text);
643 vim_free(term->tl_opencmd); 653 vim_free(term->tl_opencmd);
644 vim_free(term->tl_eof_chars); 654 vim_free(term->tl_eof_chars);
655 if (desired_cursor_color == term->tl_cursor_color)
656 desired_cursor_color = (char_u *)"";
645 vim_free(term->tl_cursor_color); 657 vim_free(term->tl_cursor_color);
646 vim_free(term); 658 vim_free(term);
647 buf->b_term = NULL; 659 buf->b_term = NULL;
648 if (in_terminal_loop == term) 660 if (in_terminal_loop == term)
649 in_terminal_loop = NULL; 661 in_terminal_loop = NULL;
1470 1482
1471 return &entry; 1483 return &entry;
1472 } 1484 }
1473 #endif 1485 #endif
1474 1486
1475 static int did_change_cursor = FALSE; 1487 static void
1476 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 }
1505
1506 /*
1507 * Set the cursor color and shape, if not last set to these.
1508 */
1477 static void 1509 static void
1478 may_set_cursor_props(term_T *term) 1510 may_set_cursor_props(term_T *term)
1479 { 1511 {
1480 #ifdef FEAT_GUI 1512 #ifdef FEAT_GUI
1481 /* For the GUI the cursor properties are obtained with 1513 /* For the GUI the cursor properties are obtained with
1483 if (gui.in_use) 1515 if (gui.in_use)
1484 return; 1516 return;
1485 #endif 1517 #endif
1486 if (in_terminal_loop == term) 1518 if (in_terminal_loop == term)
1487 { 1519 {
1488 did_change_cursor = TRUE;
1489 if (term->tl_cursor_color != NULL) 1520 if (term->tl_cursor_color != NULL)
1490 term_cursor_color(term->tl_cursor_color); 1521 desired_cursor_color = term->tl_cursor_color;
1491 else 1522 else
1492 term_cursor_color((char_u *)""); 1523 desired_cursor_color = (char_u *)"";
1493 term_cursor_shape(term->tl_cursor_shape, term->tl_cursor_blink); 1524 desired_cursor_shape = term->tl_cursor_shape;
1494 } 1525 desired_cursor_blink = term->tl_cursor_blink;
1495 } 1526 may_output_cursor_props();
1496 1527 }
1528 }
1529
1530 /*
1531 * Reset the desired cursor properties and restore them when needed.
1532 */
1497 static void 1533 static void
1498 may_restore_cursor_props(void) 1534 prepare_restore_cursor_props(void)
1499 { 1535 {
1500 #ifdef FEAT_GUI 1536 #ifdef FEAT_GUI
1501 if (gui.in_use) 1537 if (gui.in_use)
1502 return; 1538 return;
1503 #endif 1539 #endif
1504 if (did_change_cursor) 1540 desired_cursor_color = (char_u *)"";
1505 { 1541 desired_cursor_shape = -1;
1506 did_change_cursor = FALSE; 1542 desired_cursor_blink = -1;
1507 term_cursor_color((char_u *)""); 1543 may_output_cursor_props();
1508 /* this will restore the initial cursor style, if possible */
1509 ui_cursor_shape_forced(TRUE);
1510 }
1511 } 1544 }
1512 1545
1513 /* 1546 /*
1514 * Returns TRUE if the current window contains a terminal and we are sending 1547 * Returns TRUE if the current window contains a terminal and we are sending
1515 * keys to the job. 1548 * keys to the job.
1542 int ret; 1575 int ret;
1543 #ifdef UNIX 1576 #ifdef UNIX
1544 int tty_fd = curbuf->b_term->tl_job->jv_channel 1577 int tty_fd = curbuf->b_term->tl_job->jv_channel
1545 ->ch_part[get_tty_part(curbuf->b_term)].ch_fd; 1578 ->ch_part[get_tty_part(curbuf->b_term)].ch_fd;
1546 #endif 1579 #endif
1580 int restore_cursor;
1547 1581
1548 /* Remember the terminal we are sending keys to. However, the terminal 1582 /* Remember the terminal we are sending keys to. However, the terminal
1549 * might be closed while waiting for a character, e.g. typing "exit" in a 1583 * might be closed while waiting for a character, e.g. typing "exit" in a
1550 * shell and ++close was used. Therefore use curbuf->b_term instead of a 1584 * shell and ++close was used. Therefore use curbuf->b_term instead of a
1551 * stored reference. */ 1585 * stored reference. */
1562 /* Repeat redrawing in case a message is received while redrawing. */ 1596 /* Repeat redrawing in case a message is received while redrawing. */
1563 while (must_redraw != 0) 1597 while (must_redraw != 0)
1564 if (update_screen(0) == FAIL) 1598 if (update_screen(0) == FAIL)
1565 break; 1599 break;
1566 update_cursor(curbuf->b_term, FALSE); 1600 update_cursor(curbuf->b_term, FALSE);
1601 restore_cursor = TRUE;
1567 1602
1568 c = term_vgetc(); 1603 c = term_vgetc();
1569 if (!term_use_loop()) 1604 if (!term_use_loop())
1570 { 1605 {
1571 /* Job finished while waiting for a character. Push back the 1606 /* Job finished while waiting for a character. Push back the
1670 c = wc; 1705 c = wc;
1671 } 1706 }
1672 # endif 1707 # endif
1673 if (send_keys_to_term(curbuf->b_term, c, TRUE) != OK) 1708 if (send_keys_to_term(curbuf->b_term, c, TRUE) != OK)
1674 { 1709 {
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
1675 ret = OK; 1715 ret = OK;
1676 goto theend; 1716 goto theend;
1677 } 1717 }
1678 } 1718 }
1679 ret = FAIL; 1719 ret = FAIL;
1680 1720
1681 theend: 1721 theend:
1682 in_terminal_loop = NULL; 1722 in_terminal_loop = NULL;
1683 may_restore_cursor_props(); 1723 if (restore_cursor)
1724 prepare_restore_cursor_props();
1684 return ret; 1725 return ret;
1685 } 1726 }
1686 1727
1687 /* 1728 /*
1688 * Called when a job has finished. 1729 * Called when a job has finished.
2003 term->tl_cursor_shape = value->number; 2044 term->tl_cursor_shape = value->number;
2004 may_set_cursor_props(term); 2045 may_set_cursor_props(term);
2005 break; 2046 break;
2006 2047
2007 case VTERM_PROP_CURSORCOLOR: 2048 case VTERM_PROP_CURSORCOLOR:
2049 if (desired_cursor_color == term->tl_cursor_color)
2050 desired_cursor_color = (char_u *)"";
2008 vim_free(term->tl_cursor_color); 2051 vim_free(term->tl_cursor_color);
2009 if (*value->string == NUL) 2052 if (*value->string == NUL)
2010 term->tl_cursor_color = NULL; 2053 term->tl_cursor_color = NULL;
2011 else 2054 else
2012 term->tl_cursor_color = vim_strsave((char_u *)value->string); 2055 term->tl_cursor_color = vim_strsave((char_u *)value->string);
3290 3333
3291 # ifndef PROTO 3334 # ifndef PROTO
3292 3335
3293 #define WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN 1ul 3336 #define WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN 1ul
3294 #define WINPTY_SPAWN_FLAG_EXIT_AFTER_SHUTDOWN 2ull 3337 #define WINPTY_SPAWN_FLAG_EXIT_AFTER_SHUTDOWN 2ull
3295 #define WINPTY_MOUSE_MODE_FORCE 2 3338 #define WINPTY_MOUSE_MODE_FORCE 2
3296 3339
3297 void* (*winpty_config_new)(UINT64, void*); 3340 void* (*winpty_config_new)(UINT64, void*);
3298 void* (*winpty_open)(void*, void*); 3341 void* (*winpty_open)(void*, void*);
3299 void* (*winpty_spawn_config_new)(UINT64, void*, LPCWSTR, void*, void*, void*); 3342 void* (*winpty_spawn_config_new)(UINT64, void*, LPCWSTR, void*, void*, void*);
3300 BOOL (*winpty_spawn)(void*, void*, HANDLE*, HANDLE*, DWORD*, void*); 3343 BOOL (*winpty_spawn)(void*, void*, HANDLE*, HANDLE*, DWORD*, void*);