Skip to content

Commit 33796b3

Browse files
committed
patch 8.1.1493: redrawing with popups is slow and causes flicker
Problem: Redrawing with popups is slow and causes flicker. Solution: Avoid clearing and redrawing using a zindex mask.
1 parent 7c348bb commit 33796b3

6 files changed

Lines changed: 225 additions & 57 deletions

File tree

src/globals.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,21 @@ EXTERN schar_T *ScreenLines2 INIT(= NULL);
7070
*/
7171
EXTERN short *TabPageIdxs INIT(= NULL);
7272

73+
#ifdef FEAT_TEXT_PROP
74+
// Array with size Rows x Columns containing zindex of popups.
75+
EXTERN short *popup_mask INIT(= NULL);
76+
77+
// Flag set to TRUE when popup_mask needs to be updated.
78+
EXTERN int popup_mask_refresh INIT(= TRUE);
79+
80+
// Tab that was used to fill popup_mask.
81+
EXTERN tabpage_T *popup_mask_tab INIT(= NULL);
82+
83+
// Zindex in for screen_char(): if lower than the value in "popup_mask"
84+
// drawing the character is skipped.
85+
EXTERN int screen_zindex INIT(= 0);
86+
#endif
87+
7388
EXTERN int screen_Rows INIT(= 0); /* actual size of ScreenLines[] */
7489
EXTERN int screen_Columns INIT(= 0); /* actual size of ScreenLines[] */
7590

src/popupmnu.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,12 @@ pum_redraw(void)
431431
/ (pum_size - pum_height);
432432
}
433433

434+
#ifdef FEAT_TEXT_PROP
435+
// The popup menu is drawn over popup menus with zindex under
436+
// POPUPMENU_ZINDEX.
437+
screen_zindex = POPUPMENU_ZINDEX;
438+
#endif
439+
434440
for (i = 0; i < pum_height; ++i)
435441
{
436442
idx = i + pum_first;
@@ -611,6 +617,10 @@ pum_redraw(void)
611617

612618
++row;
613619
}
620+
621+
#ifdef FEAT_TEXT_PROP
622+
screen_zindex = 0;
623+
#endif
614624
}
615625

616626
/*

src/popupwin.c

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,12 @@ apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict)
185185
get_pos_options(wp, dict);
186186

187187
wp->w_zindex = dict_get_number(dict, (char_u *)"zindex");
188+
if (wp->w_zindex < 1)
189+
wp->w_zindex = POPUPWIN_DEFAULT_ZINDEX;
190+
if (wp->w_zindex > 32000)
191+
wp->w_zindex = 32000;
188192

189-
#if defined(FEAT_TIMERS)
193+
# if defined(FEAT_TIMERS)
190194
// Add timer to close the popup after some time.
191195
nr = dict_get_number(dict, (char_u *)"time");
192196
if (nr > 0)
@@ -204,7 +208,7 @@ apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict)
204208
clear_tv(&tv);
205209
}
206210
}
207-
#endif
211+
# endif
208212

209213
// Option values resulting in setting an option.
210214
str = dict_get_string(dict, (char_u *)"highlight", FALSE);
@@ -330,6 +334,8 @@ apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict)
330334
else
331335
semsg(_(e_invarg2), tv_get_string(&di->di_tv));
332336
}
337+
338+
popup_mask_refresh = TRUE;
333339
}
334340

335341
/*
@@ -435,6 +441,10 @@ popup_adjust_position(win_T *wp)
435441
int left_extra = wp->w_popup_border[3] + wp->w_popup_padding[3];
436442
int extra_height = top_extra + bot_extra;
437443
int extra_width = left_extra + right_extra;
444+
int org_winrow = wp->w_winrow;
445+
int org_wincol = wp->w_wincol;
446+
int org_width = wp->w_width;
447+
int org_height = wp->w_height;
438448

439449
wp->w_winrow = 0;
440450
wp->w_wincol = 0;
@@ -554,6 +564,16 @@ popup_adjust_position(win_T *wp)
554564
}
555565

556566
wp->w_popup_last_changedtick = CHANGEDTICK(wp->w_buffer);
567+
568+
// Need to update popup_mask if the position or size changed.
569+
if (org_winrow != wp->w_winrow
570+
|| org_wincol != wp->w_wincol
571+
|| org_width != wp->w_width
572+
|| org_height != wp->w_height)
573+
{
574+
redraw_all_later(NOT_VALID);
575+
popup_mask_refresh = TRUE;
576+
}
557577
}
558578

559579
typedef enum
@@ -565,7 +585,7 @@ typedef enum
565585
/*
566586
* popup_create({text}, {options})
567587
* popup_atcursor({text}, {options})
568-
* When called from f_popup_atcursor() "atcursor" is TRUE.
588+
* When called from f_popup_atcursor() "type" is TYPE_ATCURSOR.
569589
*/
570590
static void
571591
popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
@@ -675,18 +695,18 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
675695
set_moved_columns(wp, FIND_STRING);
676696
}
677697

698+
// set default values
699+
wp->w_zindex = POPUPWIN_DEFAULT_ZINDEX;
700+
678701
// Deal with options.
679702
apply_options(wp, buf, argvars[1].vval.v_dict);
680703

681-
// set default values
682-
if (wp->w_zindex == 0)
683-
wp->w_zindex = 50;
684-
685704
popup_adjust_position(wp);
686705

687706
wp->w_vsep_width = 0;
688707

689708
redraw_all_later(NOT_VALID);
709+
popup_mask_refresh = TRUE;
690710
}
691711

692712
/*
@@ -815,6 +835,7 @@ f_popup_hide(typval_T *argvars, typval_T *rettv UNUSED)
815835
wp->w_popup_flags |= POPF_HIDDEN;
816836
--wp->w_buffer->b_nwindows;
817837
redraw_all_later(NOT_VALID);
838+
popup_mask_refresh = TRUE;
818839
}
819840
}
820841

@@ -832,6 +853,7 @@ f_popup_show(typval_T *argvars, typval_T *rettv UNUSED)
832853
wp->w_popup_flags &= ~POPF_HIDDEN;
833854
++wp->w_buffer->b_nwindows;
834855
redraw_all_later(NOT_VALID);
856+
popup_mask_refresh = TRUE;
835857
}
836858
}
837859

@@ -843,6 +865,7 @@ popup_free(win_T *wp)
843865
clear_cmdline = TRUE;
844866
win_free_popup(wp);
845867
redraw_all_later(NOT_VALID);
868+
popup_mask_refresh = TRUE;
846869
}
847870

848871
/*
@@ -944,7 +967,6 @@ f_popup_move(typval_T *argvars, typval_T *rettv UNUSED)
944967
if (wp->w_winrow + wp->w_height >= cmdline_row)
945968
clear_cmdline = TRUE;
946969
popup_adjust_position(wp);
947-
redraw_all_later(NOT_VALID);
948970
}
949971

950972
/*
@@ -984,7 +1006,7 @@ f_popup_getpos(typval_T *argvars, typval_T *rettv)
9841006
}
9851007

9861008
/*
987-
* f_popup_getoptions({id})
1009+
* popup_getoptions({id})
9881010
*/
9891011
void
9901012
f_popup_getoptions(typval_T *argvars, typval_T *rettv)

src/proto/screen.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ int update_screen(int type_arg);
1616
int conceal_cursor_line(win_T *wp);
1717
void conceal_check_cursor_line(void);
1818
void update_debug_sign(buf_T *buf, linenr_T lnum);
19+
int may_update_popup_mask(int type_arg);
1920
void updateWindow(win_T *wp);
2021
int screen_get_current_line_off(void);
2122
void screen_line(int row, int coloff, int endcol, int clear_width, int flags);

0 commit comments

Comments
 (0)