]> granicus.if.org Git - vim/commitdiff
patch 8.2.3801: if a terminal shows in two windows, only one is redrawn v8.2.3801
authorBram Moolenaar <Bram@vim.org>
Mon, 13 Dec 2021 21:59:09 +0000 (21:59 +0000)
committerBram Moolenaar <Bram@vim.org>
Mon, 13 Dec 2021 21:59:09 +0000 (21:59 +0000)
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)

src/drawscreen.c
src/proto/terminal.pro
src/terminal.c
src/testdir/test_terminal.vim
src/version.c

index 106ae95ca5fed01c745e8b27bd0299a8ec83928b..28a2072959fed176a9702e1649668821cf99e523 100644 (file)
@@ -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
index d814bc835cb05d0263d856047cd1d89f4ef782e5..996ac70e238559bcf545fe31f831b32e6c60c576 100644 (file)
@@ -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);
index f584200844fc2e29e4cd2f2c0c553066feac5c31..f8dc219b41faca4327026e9e8a89a933bab1b8ea 100644 (file)
@@ -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;
+    }
 }
 
 /*
index 3efc6bbc50cb4f4576359ea7255b444fa0f9f4e9..68013a3afa15d2ec8e726c5660a43ffeb978a186 100644 (file)
@@ -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('$'))
index c39adda3c3aaa3afb1d5fffc20dc37a2c262862c..8f0b954910ccba14876625f54eb801f2e1bc01ea 100644 (file)
@@ -749,6 +749,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3801,
 /**/
     3800,
 /**/