# HG changeset patch # User Bram Moolenaar # Date 1619205304 -7200 # Node ID a878e5e892cf40e2281a7de9c0c511e3d3cd205c # Parent df39b96338bbbebda2e06912bd8ed0e93348794a patch 8.2.2803: flicker when the popup menu has an info popup Commit: https://github.com/vim/vim/commit/e0c03c8e107f109eadab145e18544d8e74a6976e Author: Bram Moolenaar Date: Fri Apr 23 21:01:34 2021 +0200 patch 8.2.2803: flicker when the popup menu has an info popup Problem: Flicker when the popup menu has an info popup. Solution: Avoid drawing over the popup when it's going to be redrawn in the same position. (closes #8131) Also avoid redrawing the scrollbar. diff --git a/src/drawscreen.c b/src/drawscreen.c --- a/src/drawscreen.c +++ b/src/drawscreen.c @@ -93,6 +93,7 @@ update_screen(int type_arg) int gui_cursor_row = 0; #endif int no_update = FALSE; + int save_pum_will_redraw = pum_will_redraw; // Don't do anything if the screen structures are (not yet) valid. if (!screen_valid(TRUE)) @@ -276,6 +277,11 @@ update_screen(int type_arg) } #endif + if (pum_redraw_in_same_position()) + // Avoid flicker if the popup menu is going to be redrawn in the same + // position. + pum_will_redraw = TRUE; + // Go from top to bottom through the windows, redrawing the ones that need // it. #if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_CLIPBOARD) @@ -321,7 +327,9 @@ update_screen(int type_arg) #if defined(FEAT_SEARCH_EXTRA) end_search_hl(); #endif + // May need to redraw the popup menu. + pum_will_redraw = save_pum_will_redraw; pum_may_redraw(); // Reset b_mod_set flags. Going through all windows is probably faster diff --git a/src/globals.h b/src/globals.h --- a/src/globals.h +++ b/src/globals.h @@ -741,6 +741,10 @@ EXTERN int popup_visible INIT(= FALSE); EXTERN int text_prop_frozen INIT(= 0); #endif +// When set the popup menu will redraw soon using the pum_win_ values. Do not +// draw over the poup menu area to avoid flicker. +EXTERN int pum_will_redraw INIT(= FALSE); + /* * The window layout is kept in a tree of frames. topframe points to the top * of the tree. diff --git a/src/popupmenu.c b/src/popupmenu.c --- a/src/popupmenu.c +++ b/src/popupmenu.c @@ -40,10 +40,6 @@ static int pum_win_width; // makes pum_visible() return FALSE even when there is a popup menu. static int pum_pretend_not_visible = FALSE; -// When set the popup menu will redraw soon using the pum_win_ values. Do not -// draw over the poup menu area to avoid flicker. -static int pum_will_redraw = FALSE; - static int pum_set_selected(int n, int repeat); #define PUM_DEF_HEIGHT 10 @@ -392,7 +388,7 @@ pum_under_menu(int row, int col) && row >= pum_row && row < pum_row + pum_height && col >= pum_col - 1 - && col < pum_col + pum_width; + && col < pum_col + pum_width + pum_scrollbar; } /* @@ -1049,6 +1045,32 @@ pum_visible(void) } /* + * Return TRUE if the popup can be redrawn in the same position. + */ + static int +pum_in_same_position(void) +{ + return pum_window != curwin + || (pum_win_row == curwin->w_wrow + W_WINROW(curwin) + && pum_win_height == curwin->w_height + && pum_win_col == curwin->w_wincol + && pum_win_width == curwin->w_width); +} + +/* + * Return TRUE when pum_may_redraw() will call pum_redraw(). + * This means that the pum area should not be overwritten to avoid flicker. + */ + int +pum_redraw_in_same_position(void) +{ + if (!pum_visible() || pum_will_redraw) + return FALSE; // nothing to do + + return pum_in_same_position(); +} + +/* * Reposition the popup menu to adjust for window layout changes. */ void @@ -1061,11 +1083,7 @@ pum_may_redraw(void) if (!pum_visible() || pum_will_redraw) return; // nothing to do - if (pum_window != curwin - || (pum_win_row == curwin->w_wrow + W_WINROW(curwin) - && pum_win_height == curwin->w_height - && pum_win_col == curwin->w_wincol - && pum_win_width == curwin->w_width)) + if (pum_in_same_position()) { // window position didn't change, redraw in the same position pum_redraw(); diff --git a/src/proto/popupmenu.pro b/src/proto/popupmenu.pro --- a/src/proto/popupmenu.pro +++ b/src/proto/popupmenu.pro @@ -7,6 +7,7 @@ void pum_position_info_popup(win_T *wp); void pum_undisplay(void); void pum_clear(void); int pum_visible(void); +int pum_redraw_in_same_position(void); void pum_may_redraw(void); int pum_get_height(void); void pum_set_event_info(dict_T *dict); diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2803, +/**/ 2802, /**/ 2801,