# HG changeset patch # User Christian Brabandt # Date 1501017303 -7200 # Node ID 98154b91e43a760460e7adb798daf0cf7c8fbd41 # Parent e22f9669e392ca47021732a0a2d00562c7403870 patch 8.0.0775: in a terminal the cursor is updated too often commit https://github.com/vim/vim/commit/fc716d725613c3b5934e7eac6573adde8e4f8183 Author: Bram Moolenaar Date: Tue Jul 25 23:08:47 2017 +0200 patch 8.0.0775: in a terminal the cursor is updated too often Problem: In a terminal the cursor is updated too often. Solution: Only flush when needed. (Yasuhiro Matsumoto). Remeber whether the cursor is visible. (closes #1873) diff --git a/src/terminal.c b/src/terminal.c --- a/src/terminal.c +++ b/src/terminal.c @@ -106,6 +106,7 @@ struct terminal_S { int tl_dirty_row_end; /* row below last one to update */ pos_T tl_cursor; + int tl_cursor_visible; }; /* @@ -176,6 +177,7 @@ ex_terminal(exarg_T *eap) if (term == NULL) return; term->tl_dirty_row_end = MAX_ROW; + term->tl_cursor_visible = TRUE; /* Open a new window or tab. */ vim_memset(&split_ea, 0, sizeof(split_ea)); @@ -316,15 +318,18 @@ term_write_job_output(term_T *term, char } static void -update_cursor() +update_cursor(term_T *term, int redraw) { /* TODO: this should not always be needed */ setcursor(); - out_flush(); + if (redraw && term->tl_buffer == curbuf && term->tl_cursor_visible) + { + out_flush(); #ifdef FEAT_GUI - if (gui.in_use) - gui_update_cursor(FALSE, FALSE); + if (gui.in_use) + gui_update_cursor(FALSE, FALSE); #endif + } } /* @@ -342,7 +347,7 @@ write_to_term(buf_T *buffer, char_u *msg /* TODO: only update once in a while. */ update_screen(0); - update_cursor(); + update_cursor(term, TRUE); } /* @@ -473,7 +478,7 @@ terminal_loop(void) { /* TODO: skip screen update when handling a sequence of keys. */ update_screen(0); - update_cursor(); + update_cursor(curbuf->b_term, FALSE); ++no_mapping; ++allow_keys; got_int = FALSE; @@ -559,12 +564,13 @@ term_job_ended(job_T *job) did_one = TRUE; } if (did_one) + redraw_statuslines(); + if (curbuf->b_term != NULL) { - redraw_statuslines(); - update_cursor(); + if (curbuf->b_term->tl_job == job) + maketitle(); + update_cursor(curbuf->b_term, TRUE); } - if (curbuf->b_term != NULL && curbuf->b_term->tl_job == job) - maketitle(); } /* @@ -583,6 +589,18 @@ position_cursor(win_T *wp, VTermPos *pos wp->w_wcol = MIN(pos->col, MAX(0, wp->w_width - 1)); } + static void +may_toggle_cursor(term_T *term) +{ + if (curbuf == term->tl_buffer) + { + if (term->tl_cursor_visible) + cursor_on(); + else + cursor_off(); + } +} + static int handle_damage(VTermRect rect, void *user) { @@ -608,7 +626,7 @@ handle_moverect(VTermRect dest UNUSED, V handle_movecursor( VTermPos pos, VTermPos oldpos UNUSED, - int visible UNUSED, + int visible, void *user) { term_T *term = (term_T *)user; @@ -625,8 +643,12 @@ handle_movecursor( } } + term->tl_cursor_visible = visible; if (is_current) - update_cursor(); + { + may_toggle_cursor(term); + update_cursor(term, TRUE); + } return 1; } @@ -648,11 +670,19 @@ handle_settermprop( term->tl_status_text = NULL; if (term == curbuf->b_term) maketitle(); - return 1; + break; + + case VTERM_PROP_CURSORVISIBLE: + term->tl_cursor_visible = value->boolean; + may_toggle_cursor(term); + out_flush(); + break; + default: break; } - return 0; + /* Always return 1, otherwise vterm doesn't store the value internally. */ + return 1; } /* diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -770,6 +770,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 775, +/**/ 774, /**/ 773,