summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-12-13 21:59:09 +0000
committerBram Moolenaar <Bram@vim.org>2021-12-13 21:59:09 +0000
commit3194e5bf87f8e08f519b947a03c46677616cd7e3 (patch)
tree6d90217b81ec8a60b93249d26a09d25b9bed4cd0
parent6840a0ffe8d27a8773a500ba17550cdf2ad12cbc (diff)
downloadvim-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.c7
-rw-r--r--src/proto/terminal.pro1
-rw-r--r--src/terminal.c18
-rw-r--r--src/testdir/test_terminal.vim27
-rw-r--r--src/version.c2
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,