# HG changeset patch # User Bram Moolenaar # Date 1582925409 -3600 # Node ID 9e428147e4eed902e0a5b9a3ea29169686a3e5a7 # Parent 80dd4d7df929303fb71bd58cdf3eee836146fb89 patch 8.2.0328: no redraw when leaving term-normal mode in popup terminal Commit: https://github.com/vim/vim/commit/e52e0c89d1a6305beca3c01f89a4892dcb43bc71 Author: Bram Moolenaar Date: Fri Feb 28 22:20:10 2020 +0100 patch 8.2.0328: no redraw when leaving term-normal mode in popup terminal Problem: No redraw when leaving terminal-normal mode in a terminal popup window. Solution: Redraw the popup window. (closes #5708) diff --git a/src/drawscreen.c b/src/drawscreen.c --- a/src/drawscreen.c +++ b/src/drawscreen.c @@ -69,6 +69,9 @@ static void win_update(win_T *wp); #ifdef FEAT_STL_OPT static void redraw_custom_statusline(win_T *wp); #endif +#if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_CLIPBOARD) +static int did_update_one_window; +#endif /* * Based on the current value of curwin->w_topline, transfer a screenfull @@ -81,10 +84,8 @@ update_screen(int type_arg) int type = type_arg; win_T *wp; static int did_intro = FALSE; -#if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_CLIPBOARD) - int did_one; -#endif #ifdef FEAT_GUI + int did_one = FALSE; int did_undraw = FALSE; int gui_cursor_col = 0; int gui_cursor_row = 0; @@ -276,7 +277,7 @@ update_screen(int type_arg) // Go from top to bottom through the windows, redrawing the ones that need // it. #if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_CLIPBOARD) - did_one = FALSE; + did_update_one_window = FALSE; #endif #ifdef FEAT_SEARCH_EXTRA screen_search_hl.rm.regprog = NULL; @@ -286,21 +287,11 @@ update_screen(int type_arg) if (wp->w_redr_type != 0) { cursor_off(); -#if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_CLIPBOARD) +#ifdef FEAT_GUI if (!did_one) { did_one = TRUE; -# ifdef FEAT_SEARCH_EXTRA - start_search_hl(); -# endif -# ifdef FEAT_CLIPBOARD - // When Visual area changed, may have to update selection. - if (clip_star.available && clip_isautosel_star()) - clip_update_selection(&clip_star); - if (clip_plus.available && clip_isautosel_plus()) - clip_update_selection(&clip_plus); -# endif -#ifdef FEAT_GUI + // Remove the cursor before starting to do anything, because // scrolling may make it difficult to redraw the text under // it. @@ -311,9 +302,9 @@ update_screen(int type_arg) gui_undraw_cursor(); did_undraw = TRUE; } -#endif } #endif + win_update(wp); } @@ -1422,6 +1413,25 @@ win_update(win_T *wp) proftime_T syntax_tm; #endif +#if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_CLIPBOARD) + // This needs to be done only for the first window when update_screen() is + // called. + if (!did_update_one_window) + { + did_update_one_window = TRUE; +# ifdef FEAT_SEARCH_EXTRA + start_search_hl(); +# endif +# ifdef FEAT_CLIPBOARD + // When Visual area changed, may have to update selection. + if (clip_star.available && clip_isautosel_star()) + clip_update_selection(&clip_star); + if (clip_plus.available && clip_isautosel_plus()) + clip_update_selection(&clip_plus); +# endif + } +#endif + type = wp->w_redr_type; if (type == NOT_VALID) @@ -3025,6 +3035,11 @@ redraw_buf_later(buf_T *buf, int type) if (wp->w_buffer == buf) redraw_win_later(wp, type); } +#if defined(FEAT_TERMINAL) && defined(FEAT_PROP_POPUP) + // terminal in popup window is not in list of windows + if (curwin->w_buffer == buf) + redraw_win_later(curwin, type); +#endif } #if defined(FEAT_SIGNS) || defined(PROTO) diff --git a/src/macros.h b/src/macros.h --- a/src/macros.h +++ b/src/macros.h @@ -344,9 +344,11 @@ // Give an error in curwin is a popup window and evaluate to TRUE. #ifdef FEAT_PROP_POPUP +# define WIN_IS_POPUP(wp) ((wp)->w_popup_flags != 0) # define ERROR_IF_POPUP_WINDOW error_if_popup_window(FALSE) # define ERROR_IF_ANY_POPUP_WINDOW error_if_popup_window(TRUE) #else +# define WIN_IS_POPUP(wp) 0 # define ERROR_IF_POPUP_WINDOW 0 # define ERROR_IF_ANY_POPUP_WINDOW 0 #endif diff --git a/src/move.c b/src/move.c --- a/src/move.c +++ b/src/move.c @@ -1174,6 +1174,13 @@ curs_columns( && !pum_visible()) redraw_later(SOME_VALID); #endif +#if defined(FEAT_PROP_POPUP) && defined(FEAT_TERMINAL) + if (popup_is_popup(curwin) && curbuf->b_term != NULL) + { + curwin->w_wrow += popup_top_extra(curwin); + curwin->w_wcol += popup_left_extra(curwin); + } +#endif // now w_leftcol is valid, avoid check_cursor_moved() thinking otherwise curwin->w_valid_leftcol = curwin->w_leftcol; diff --git a/src/popupwin.c b/src/popupwin.c --- a/src/popupwin.c +++ b/src/popupwin.c @@ -3505,9 +3505,12 @@ update_popups(void (*win_update)(win_T * wp->w_winrow -= top_off; wp->w_wincol -= left_extra; - // cursor position matters in terminal - wp->w_wrow += top_off; - wp->w_wcol += left_extra; + // cursor position matters in terminal in job mode + if (wp != curwin || !term_in_normal_mode()) + { + wp->w_wrow += top_off; + wp->w_wcol += left_extra; + } total_width = popup_width(wp); total_height = popup_height(wp); diff --git a/src/terminal.c b/src/terminal.c --- a/src/terminal.c +++ b/src/terminal.c @@ -1796,6 +1796,27 @@ update_snapshot(term_T *term) } /* + * Loop over all windows in the current tab, and also curwin, which is not + * encountered when using a terminal in a popup window. + * Return TRUE if "*wp" was set to the next window. + */ + static int +for_all_windows_and_curwin(win_T **wp, int *did_curwin) +{ + if (*wp == NULL) + *wp = firstwin; + else if ((*wp)->w_next != NULL) + *wp = (*wp)->w_next; + else if (!*did_curwin) + *wp = curwin; + else + return FALSE; + if (*wp == curwin) + *did_curwin = TRUE; + return TRUE; +} + +/* * If needed, add the current lines of the terminal to scrollback and to the * buffer. Called after the job has ended and when switching to * Terminal-Normal mode. @@ -1804,8 +1825,6 @@ update_snapshot(term_T *term) static void may_move_terminal_to_buffer(term_T *term, int redraw) { - win_T *wp; - if (term->tl_vterm == NULL) return; @@ -1820,7 +1839,11 @@ may_move_terminal_to_buffer(term_T *term &term->tl_default_color.fg, &term->tl_default_color.bg); if (redraw) - FOR_ALL_WINDOWS(wp) + { + win_T *wp = NULL; + int did_curwin = FALSE; + + while (for_all_windows_and_curwin(&wp, &did_curwin)) { if (wp->w_buffer == term->tl_buffer) { @@ -1837,6 +1860,7 @@ may_move_terminal_to_buffer(term_T *term redraw_win_later(wp, NOT_VALID); } } + } } #if defined(FEAT_TIMERS) || defined(PROTO) @@ -1920,6 +1944,7 @@ term_enter_normal_mode(void) check_cursor(); if (coladvance(term->tl_cursor_pos.col) == FAIL) coladvance(MAXCOL); + curwin->w_set_curswant = TRUE; // Display the same lines as in the terminal. curwin->w_topline = term->tl_scrollback_scrolled + 1; @@ -1951,6 +1976,10 @@ term_enter_job_mode() if (term->tl_channel_closed) cleanup_vterm(term); redraw_buf_and_status_later(curbuf, NOT_VALID); +#ifdef FEAT_PROP_POPUP + if (WIN_IS_POPUP(curwin)) + redraw_win_later(curwin, NOT_VALID); +#endif } /* @@ -2801,14 +2830,15 @@ handle_damage(VTermRect rect, void *user static void term_scroll_up(term_T *term, int start_row, int count) { - win_T *wp; + win_T *wp = NULL; + int did_curwin = FALSE; VTermColor fg, bg; VTermScreenCellAttrs attr; int clear_attr; vim_memset(&attr, 0, sizeof(attr)); - FOR_ALL_WINDOWS(wp) + while (for_all_windows_and_curwin(&wp, &did_curwin)) { if (wp->w_buffer == term->tl_buffer) { @@ -2858,12 +2888,13 @@ handle_movecursor( void *user) { term_T *term = (term_T *)user; - win_T *wp; + win_T *wp = NULL; + int did_curwin = FALSE; term->tl_cursor_pos = pos; term->tl_cursor_visible = visible; - FOR_ALL_WINDOWS(wp) + while (for_all_windows_and_curwin(&wp, &did_curwin)) { if (wp->w_buffer == term->tl_buffer) position_cursor(wp, &pos, FALSE); diff --git a/src/testdir/dumps/Test_terminal_popup_7.dump b/src/testdir/dumps/Test_terminal_popup_7.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_terminal_popup_7.dump @@ -0,0 +1,15 @@ +|0+0&#ffffff0| @73 +|1| @73 +|2| @73 +|3| @12|╔+0#0000001#ffd7ff255|═@44|╗| +0#0000000#ffffff0@13 +|4| @12|║+0#0000001#ffd7ff255|s|o|m|e| |t|e|x|t| @35|║| +0#0000000#ffffff0@13 +|5| @12|║+0#0000001#ffd7ff255|t|o| |e+0&#ffff4012|d|i|t| +0&#ffd7ff255@37|║| +0#0000000#ffffff0@13 +|6| @12|║+0#0000001#ffd7ff255|i+0&#e0e0e08|n| |a| >p+0&#ffd7ff255|o|p|u|p| |w|i|n|d|o|w| @27|║| +0#0000000#ffffff0@13 +|7| @12|║+0#0000001#ffd7ff255|~+0#4040ff13&| @43|║+0#0000001&| +0#0000000#ffffff0@13 +|8| @12|║+0#0000001#ffd7ff255|~+0#4040ff13&| @43|║+0#0000001&| +0#0000000#ffffff0@13 +|9| @12|║+0#0000001#ffd7ff255|~+0#4040ff13&| @43|║+0#0000001&| +0#0000000#ffffff0@13 +|1|0| @11|║+0#0000001#ffd7ff255|/|e|d|i|t| @21|2|,|4| @10|A|l@1| |║| +0#0000000#ffffff0@13 +|1@1| @11|╚+0#0000001#ffd7ff255|═@44|╝| +0#0000000#ffffff0@13 +|1|2| @72 +|1|3| @72 +|-+2&&@1| |V|I|S|U|A|L| |-@1| +0&&@34|6| @8|3|,|6| @10|A|l@1| diff --git a/src/testdir/dumps/Test_terminal_popup_8.dump b/src/testdir/dumps/Test_terminal_popup_8.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_terminal_popup_8.dump @@ -0,0 +1,15 @@ +|0+0&#ffffff0| @73 +|1| @73 +|2| @73 +|3| @12|╔+0#0000001#ffd7ff255|═@44|╗| +0#0000000#ffffff0@13 +|4| @12|║+0#0000001#ffd7ff255|s+0#0000000#ffffff0|o|m|e| |t|e|x|t| @35|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@13 +|5| @12|║+0#0000001#ffd7ff255|t+0#0000000#ffffff0|o| >e+0&#ffff4012|d|i|t| +0&#ffffff0@37|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@13 +|6| @12|║+0#0000001#ffd7ff255|i+0#0000000#ffffff0|n| |a| |p|o|p|u|p| |w|i|n|d|o|w| @27|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@13 +|7| @12|║+0#0000001#ffd7ff255|~+0#4040ff13#ffffff0| @43|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@13 +|8| @12|║+0#0000001#ffd7ff255|~+0#4040ff13#ffffff0| @43|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@13 +|9| @12|║+0#0000001#ffd7ff255|~+0#4040ff13#ffffff0| @43|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@13 +|1|0| @11|║+0#0000001#ffd7ff255|/+0#0000000#ffffff0|e|d|i|t| @21|2|,|4| @10|A|l@1| |║+0#0000001#ffd7ff255| +0#0000000#ffffff0@13 +|1@1| @11|╚+0#0000001#ffd7ff255|═@44|╝| +0#0000000#ffffff0@13 +|1|2| @72 +|1|3| @72 +@57|1|,|1| @10|T|o|p| diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim --- a/src/testdir/test_terminal.vim +++ b/src/testdir/test_terminal.vim @@ -2382,8 +2382,16 @@ func Test_terminal_in_popup() call term_sendkeys(buf, "\:call ReopenPopup()\") call VerifyScreenDump(buf, 'Test_terminal_popup_6', {}) + + " Go to terminal-Normal mode and visually select text. + call term_sendkeys(buf, "\Ngg/in\vww") + call VerifyScreenDump(buf, 'Test_terminal_popup_7', {}) + + " Back to job mode, redraws + call term_sendkeys(buf, "A") + call VerifyScreenDump(buf, 'Test_terminal_popup_8', {}) + call term_wait(buf, 100) - call term_sendkeys(buf, ":q\") call term_wait(buf, 100) " wait for terminal to vanish diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -739,6 +739,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 328, +/**/ 327, /**/ 326, diff --git a/src/vim.h b/src/vim.h --- a/src/vim.h +++ b/src/vim.h @@ -640,12 +640,6 @@ extern int (*dyn_libintl_wputenv)(const #define POPUP_HANDLED_4 0x08 // used by may_update_popup_mask() #define POPUP_HANDLED_5 0x10 // used by update_popups() -#ifdef FEAT_PROP_POPUP -# define WIN_IS_POPUP(wp) ((wp)->w_popup_flags != 0) -#else -# define WIN_IS_POPUP(wp) 0 -#endif - /* * Terminal highlighting attribute bits. * Attributes above HL_ALL are used for syntax highlighting.