comparison src/terminal.c @ 11786:98154b91e43a v8.0.0775

patch 8.0.0775: in a terminal the cursor is updated too often commit https://github.com/vim/vim/commit/fc716d725613c3b5934e7eac6573adde8e4f8183 Author: Bram Moolenaar <Bram@vim.org> 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)
author Christian Brabandt <cb@256bit.org>
date Tue, 25 Jul 2017 23:15:03 +0200
parents e8005055f845
children 4dfebc1b2674
comparison
equal deleted inserted replaced
11785:e22f9669e392 11786:98154b91e43a
104 /* Range of screen rows to update. Zero based. */ 104 /* Range of screen rows to update. Zero based. */
105 int tl_dirty_row_start; /* -1 if nothing dirty */ 105 int tl_dirty_row_start; /* -1 if nothing dirty */
106 int tl_dirty_row_end; /* row below last one to update */ 106 int tl_dirty_row_end; /* row below last one to update */
107 107
108 pos_T tl_cursor; 108 pos_T tl_cursor;
109 int tl_cursor_visible;
109 }; 110 };
110 111
111 /* 112 /*
112 * List of all active terminals. 113 * List of all active terminals.
113 */ 114 */
174 175
175 term = (term_T *)alloc_clear(sizeof(term_T)); 176 term = (term_T *)alloc_clear(sizeof(term_T));
176 if (term == NULL) 177 if (term == NULL)
177 return; 178 return;
178 term->tl_dirty_row_end = MAX_ROW; 179 term->tl_dirty_row_end = MAX_ROW;
180 term->tl_cursor_visible = TRUE;
179 181
180 /* Open a new window or tab. */ 182 /* Open a new window or tab. */
181 vim_memset(&split_ea, 0, sizeof(split_ea)); 183 vim_memset(&split_ea, 0, sizeof(split_ea));
182 split_ea.cmdidx = CMD_new; 184 split_ea.cmdidx = CMD_new;
183 split_ea.cmd = (char_u *)"new"; 185 split_ea.cmd = (char_u *)"new";
314 /* this invokes the damage callbacks */ 316 /* this invokes the damage callbacks */
315 vterm_screen_flush_damage(vterm_obtain_screen(vterm)); 317 vterm_screen_flush_damage(vterm_obtain_screen(vterm));
316 } 318 }
317 319
318 static void 320 static void
319 update_cursor() 321 update_cursor(term_T *term, int redraw)
320 { 322 {
321 /* TODO: this should not always be needed */ 323 /* TODO: this should not always be needed */
322 setcursor(); 324 setcursor();
323 out_flush(); 325 if (redraw && term->tl_buffer == curbuf && term->tl_cursor_visible)
326 {
327 out_flush();
324 #ifdef FEAT_GUI 328 #ifdef FEAT_GUI
325 if (gui.in_use) 329 if (gui.in_use)
326 gui_update_cursor(FALSE, FALSE); 330 gui_update_cursor(FALSE, FALSE);
327 #endif 331 #endif
332 }
328 } 333 }
329 334
330 /* 335 /*
331 * Invoked when "msg" output from a job was received. Write it to the terminal 336 * Invoked when "msg" output from a job was received. Write it to the terminal
332 * of "buffer". 337 * of "buffer".
340 ch_logn(channel, "writing %d bytes to terminal", (int)len); 345 ch_logn(channel, "writing %d bytes to terminal", (int)len);
341 term_write_job_output(term, msg, len); 346 term_write_job_output(term, msg, len);
342 347
343 /* TODO: only update once in a while. */ 348 /* TODO: only update once in a while. */
344 update_screen(0); 349 update_screen(0);
345 update_cursor(); 350 update_cursor(term, TRUE);
346 } 351 }
347 352
348 /* 353 /*
349 * Convert typed key "c" into bytes to send to the job. 354 * Convert typed key "c" into bytes to send to the job.
350 * Return the number of bytes in "buf". 355 * Return the number of bytes in "buf".
471 476
472 for (;;) 477 for (;;)
473 { 478 {
474 /* TODO: skip screen update when handling a sequence of keys. */ 479 /* TODO: skip screen update when handling a sequence of keys. */
475 update_screen(0); 480 update_screen(0);
476 update_cursor(); 481 update_cursor(curbuf->b_term, FALSE);
477 ++no_mapping; 482 ++no_mapping;
478 ++allow_keys; 483 ++allow_keys;
479 got_int = FALSE; 484 got_int = FALSE;
480 c = vgetc(); 485 c = vgetc();
481 --no_mapping; 486 --no_mapping;
557 term->tl_status_text = NULL; 562 term->tl_status_text = NULL;
558 redraw_buf_and_status_later(term->tl_buffer, VALID); 563 redraw_buf_and_status_later(term->tl_buffer, VALID);
559 did_one = TRUE; 564 did_one = TRUE;
560 } 565 }
561 if (did_one) 566 if (did_one)
562 {
563 redraw_statuslines(); 567 redraw_statuslines();
564 update_cursor(); 568 if (curbuf->b_term != NULL)
565 } 569 {
566 if (curbuf->b_term != NULL && curbuf->b_term->tl_job == job) 570 if (curbuf->b_term->tl_job == job)
567 maketitle(); 571 maketitle();
572 update_cursor(curbuf->b_term, TRUE);
573 }
568 } 574 }
569 575
570 /* 576 /*
571 * Return TRUE if the job for "buf" is still running. 577 * Return TRUE if the job for "buf" is still running.
572 */ 578 */
579 static void 585 static void
580 position_cursor(win_T *wp, VTermPos *pos) 586 position_cursor(win_T *wp, VTermPos *pos)
581 { 587 {
582 wp->w_wrow = MIN(pos->row, MAX(0, wp->w_height - 1)); 588 wp->w_wrow = MIN(pos->row, MAX(0, wp->w_height - 1));
583 wp->w_wcol = MIN(pos->col, MAX(0, wp->w_width - 1)); 589 wp->w_wcol = MIN(pos->col, MAX(0, wp->w_width - 1));
590 }
591
592 static void
593 may_toggle_cursor(term_T *term)
594 {
595 if (curbuf == term->tl_buffer)
596 {
597 if (term->tl_cursor_visible)
598 cursor_on();
599 else
600 cursor_off();
601 }
584 } 602 }
585 603
586 static int 604 static int
587 handle_damage(VTermRect rect, void *user) 605 handle_damage(VTermRect rect, void *user)
588 { 606 {
606 624
607 static int 625 static int
608 handle_movecursor( 626 handle_movecursor(
609 VTermPos pos, 627 VTermPos pos,
610 VTermPos oldpos UNUSED, 628 VTermPos oldpos UNUSED,
611 int visible UNUSED, 629 int visible,
612 void *user) 630 void *user)
613 { 631 {
614 term_T *term = (term_T *)user; 632 term_T *term = (term_T *)user;
615 win_T *wp; 633 win_T *wp;
616 int is_current = FALSE; 634 int is_current = FALSE;
623 if (wp == curwin) 641 if (wp == curwin)
624 is_current = TRUE; 642 is_current = TRUE;
625 } 643 }
626 } 644 }
627 645
646 term->tl_cursor_visible = visible;
628 if (is_current) 647 if (is_current)
629 update_cursor(); 648 {
649 may_toggle_cursor(term);
650 update_cursor(term, TRUE);
651 }
630 652
631 return 1; 653 return 1;
632 } 654 }
633 655
634 static int 656 static int
646 term->tl_title = vim_strsave((char_u *)value->string); 668 term->tl_title = vim_strsave((char_u *)value->string);
647 vim_free(term->tl_status_text); 669 vim_free(term->tl_status_text);
648 term->tl_status_text = NULL; 670 term->tl_status_text = NULL;
649 if (term == curbuf->b_term) 671 if (term == curbuf->b_term)
650 maketitle(); 672 maketitle();
651 return 1; 673 break;
674
675 case VTERM_PROP_CURSORVISIBLE:
676 term->tl_cursor_visible = value->boolean;
677 may_toggle_cursor(term);
678 out_flush();
679 break;
680
652 default: 681 default:
653 break; 682 break;
654 } 683 }
655 return 0; 684 /* Always return 1, otherwise vterm doesn't store the value internally. */
685 return 1;
656 } 686 }
657 687
658 /* 688 /*
659 * The job running in the terminal resized the terminal. 689 * The job running in the terminal resized the terminal.
660 */ 690 */