Mercurial > vim
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*); |