diff options
author | Bram Moolenaar <Bram@vim.org> | 2021-12-13 21:59:09 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-12-13 21:59:09 +0000 |
commit | 3194e5bf87f8e08f519b947a03c46677616cd7e3 (patch) | |
tree | 6d90217b81ec8a60b93249d26a09d25b9bed4cd0 | |
parent | 6840a0ffe8d27a8773a500ba17550cdf2ad12cbc (diff) | |
download | vim-git-3194e5bf87f8e08f519b947a03c46677616cd7e3.tar.gz |
patch 8.2.3801: if a terminal shows in two windows, only one is redrawnv8.2.3801
Problem: If a terminal shows in two windows, only one is redrawn.
Solution: Reset the dirty row range only after redrawing all windows.
(closes #9341)
-rw-r--r-- | src/drawscreen.c | 7 | ||||
-rw-r--r-- | src/proto/terminal.pro | 1 | ||||
-rw-r--r-- | src/terminal.c | 18 | ||||
-rw-r--r-- | src/testdir/test_terminal.vim | 27 | ||||
-rw-r--r-- | src/version.c | 2 |
5 files changed, 53 insertions, 2 deletions
diff --git a/src/drawscreen.c b/src/drawscreen.c index 106ae95ca..28a207295 100644 --- a/src/drawscreen.c +++ b/src/drawscreen.c @@ -342,6 +342,13 @@ update_screen(int type_arg) update_popups(win_update); #endif +#ifdef FEAT_TERMINAL + FOR_ALL_WINDOWS(wp) + // If this window contains a terminal, after redrawing all windows, the + // dirty row range can be reset. + term_did_update_window(wp); +#endif + after_updating_screen(TRUE); // Clear or redraw the command line. Done last, because scrolling may diff --git a/src/proto/terminal.pro b/src/proto/terminal.pro index d814bc835..996ac70e2 100644 --- a/src/proto/terminal.pro +++ b/src/proto/terminal.pro @@ -26,6 +26,7 @@ void term_channel_closed(channel_T *ch); void term_check_channel_closed_recently(void); int term_do_update_window(win_T *wp); void term_update_window(win_T *wp); +void term_did_update_window(win_T *wp); int term_is_finished(buf_T *buf); int term_show_buffer(buf_T *buf); void term_change_in_curbuf(void); diff --git a/src/terminal.c b/src/terminal.c index f58420084..f8dc219b4 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -3850,8 +3850,22 @@ term_update_window(win_T *wp) #endif 0); } - term->tl_dirty_row_start = MAX_ROW; - term->tl_dirty_row_end = 0; +} + +/* + * Called after updating all windows: may reset dirty rows. + */ + void +term_did_update_window(win_T *wp) +{ + term_T *term = wp->w_buffer->b_term; + + if (term != NULL && term->tl_vterm != NULL && !term->tl_normal_mode + && wp->w_redr_type == 0) + { + term->tl_dirty_row_start = MAX_ROW; + term->tl_dirty_row_end = 0; + } } /* diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim index 3efc6bbc5..68013a3af 100644 --- a/src/testdir/test_terminal.vim +++ b/src/testdir/test_terminal.vim @@ -1377,6 +1377,32 @@ func Test_terminal_popup_bufload() exe 'bwipe! ' .. newbuf endfunc +func Test_terminal_popup_two_windows() + CheckScreendump + CheckUnix + + " use "sh" instead of "&shell" in the hope it will use a short prompt + let lines =<< trim END + let termbuf = term_start('sh', #{hidden: v:true, term_finish: 'close'}) + exe 'buffer ' .. termbuf + + let winid = popup_create(termbuf, #{line: 2, minwidth: 30, border: []}) + sleep 50m + + call term_sendkeys(termbuf, "echo 'test'") + END + call writefile(lines, 'XpopupScript') + let buf = RunVimInTerminal('-S XpopupScript', {}) + + " typed text appears both in normal window and in popup + call WaitForAssert({-> assert_match("echo 'test'", term_getline(buf, 1))}) + call WaitForAssert({-> assert_match("echo 'test'", term_getline(buf, 3))}) + + call term_sendkeys(buf, "\<CR>exit\<CR>:q\<CR>") + call StopVimInTerminal(buf) + call delete('XpopupScript') +endfunc + func Test_terminal_popup_insert_cmd() CheckUnix @@ -1402,6 +1428,7 @@ endfunc func Test_terminal_dumpwrite_composing() CheckRunVimInTerminal + let save_enc = &encoding set encoding=utf-8 call assert_equal(1, winnr('$')) diff --git a/src/version.c b/src/version.c index c39adda3c..8f0b95491 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3801, +/**/ 3800, /**/ 3799, |