forked from aniani/vim
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.
This commit is contained in:
parent
7c348bb5ad
commit
33796b39b9
@ -70,6 +70,21 @@ EXTERN schar_T *ScreenLines2 INIT(= NULL);
|
|||||||
*/
|
*/
|
||||||
EXTERN short *TabPageIdxs INIT(= NULL);
|
EXTERN short *TabPageIdxs INIT(= NULL);
|
||||||
|
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
// Array with size Rows x Columns containing zindex of popups.
|
||||||
|
EXTERN short *popup_mask INIT(= NULL);
|
||||||
|
|
||||||
|
// Flag set to TRUE when popup_mask needs to be updated.
|
||||||
|
EXTERN int popup_mask_refresh INIT(= TRUE);
|
||||||
|
|
||||||
|
// Tab that was used to fill popup_mask.
|
||||||
|
EXTERN tabpage_T *popup_mask_tab INIT(= NULL);
|
||||||
|
|
||||||
|
// Zindex in for screen_char(): if lower than the value in "popup_mask"
|
||||||
|
// drawing the character is skipped.
|
||||||
|
EXTERN int screen_zindex INIT(= 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
EXTERN int screen_Rows INIT(= 0); /* actual size of ScreenLines[] */
|
EXTERN int screen_Rows INIT(= 0); /* actual size of ScreenLines[] */
|
||||||
EXTERN int screen_Columns INIT(= 0); /* actual size of ScreenLines[] */
|
EXTERN int screen_Columns INIT(= 0); /* actual size of ScreenLines[] */
|
||||||
|
|
||||||
|
@ -431,6 +431,12 @@ pum_redraw(void)
|
|||||||
/ (pum_size - pum_height);
|
/ (pum_size - pum_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
// The popup menu is drawn over popup menus with zindex under
|
||||||
|
// POPUPMENU_ZINDEX.
|
||||||
|
screen_zindex = POPUPMENU_ZINDEX;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < pum_height; ++i)
|
for (i = 0; i < pum_height; ++i)
|
||||||
{
|
{
|
||||||
idx = i + pum_first;
|
idx = i + pum_first;
|
||||||
@ -611,6 +617,10 @@ pum_redraw(void)
|
|||||||
|
|
||||||
++row;
|
++row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
screen_zindex = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -185,8 +185,12 @@ apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict)
|
|||||||
get_pos_options(wp, dict);
|
get_pos_options(wp, dict);
|
||||||
|
|
||||||
wp->w_zindex = dict_get_number(dict, (char_u *)"zindex");
|
wp->w_zindex = dict_get_number(dict, (char_u *)"zindex");
|
||||||
|
if (wp->w_zindex < 1)
|
||||||
|
wp->w_zindex = POPUPWIN_DEFAULT_ZINDEX;
|
||||||
|
if (wp->w_zindex > 32000)
|
||||||
|
wp->w_zindex = 32000;
|
||||||
|
|
||||||
#if defined(FEAT_TIMERS)
|
# if defined(FEAT_TIMERS)
|
||||||
// Add timer to close the popup after some time.
|
// Add timer to close the popup after some time.
|
||||||
nr = dict_get_number(dict, (char_u *)"time");
|
nr = dict_get_number(dict, (char_u *)"time");
|
||||||
if (nr > 0)
|
if (nr > 0)
|
||||||
@ -204,7 +208,7 @@ apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict)
|
|||||||
clear_tv(&tv);
|
clear_tv(&tv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
// Option values resulting in setting an option.
|
// Option values resulting in setting an option.
|
||||||
str = dict_get_string(dict, (char_u *)"highlight", FALSE);
|
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)
|
|||||||
else
|
else
|
||||||
semsg(_(e_invarg2), tv_get_string(&di->di_tv));
|
semsg(_(e_invarg2), tv_get_string(&di->di_tv));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
popup_mask_refresh = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -435,6 +441,10 @@ popup_adjust_position(win_T *wp)
|
|||||||
int left_extra = wp->w_popup_border[3] + wp->w_popup_padding[3];
|
int left_extra = wp->w_popup_border[3] + wp->w_popup_padding[3];
|
||||||
int extra_height = top_extra + bot_extra;
|
int extra_height = top_extra + bot_extra;
|
||||||
int extra_width = left_extra + right_extra;
|
int extra_width = left_extra + right_extra;
|
||||||
|
int org_winrow = wp->w_winrow;
|
||||||
|
int org_wincol = wp->w_wincol;
|
||||||
|
int org_width = wp->w_width;
|
||||||
|
int org_height = wp->w_height;
|
||||||
|
|
||||||
wp->w_winrow = 0;
|
wp->w_winrow = 0;
|
||||||
wp->w_wincol = 0;
|
wp->w_wincol = 0;
|
||||||
@ -554,6 +564,16 @@ popup_adjust_position(win_T *wp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
wp->w_popup_last_changedtick = CHANGEDTICK(wp->w_buffer);
|
wp->w_popup_last_changedtick = CHANGEDTICK(wp->w_buffer);
|
||||||
|
|
||||||
|
// Need to update popup_mask if the position or size changed.
|
||||||
|
if (org_winrow != wp->w_winrow
|
||||||
|
|| org_wincol != wp->w_wincol
|
||||||
|
|| org_width != wp->w_width
|
||||||
|
|| org_height != wp->w_height)
|
||||||
|
{
|
||||||
|
redraw_all_later(NOT_VALID);
|
||||||
|
popup_mask_refresh = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
@ -565,7 +585,7 @@ typedef enum
|
|||||||
/*
|
/*
|
||||||
* popup_create({text}, {options})
|
* popup_create({text}, {options})
|
||||||
* popup_atcursor({text}, {options})
|
* popup_atcursor({text}, {options})
|
||||||
* When called from f_popup_atcursor() "atcursor" is TRUE.
|
* When called from f_popup_atcursor() "type" is TYPE_ATCURSOR.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
|
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)
|
|||||||
set_moved_columns(wp, FIND_STRING);
|
set_moved_columns(wp, FIND_STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set default values
|
||||||
|
wp->w_zindex = POPUPWIN_DEFAULT_ZINDEX;
|
||||||
|
|
||||||
// Deal with options.
|
// Deal with options.
|
||||||
apply_options(wp, buf, argvars[1].vval.v_dict);
|
apply_options(wp, buf, argvars[1].vval.v_dict);
|
||||||
|
|
||||||
// set default values
|
|
||||||
if (wp->w_zindex == 0)
|
|
||||||
wp->w_zindex = 50;
|
|
||||||
|
|
||||||
popup_adjust_position(wp);
|
popup_adjust_position(wp);
|
||||||
|
|
||||||
wp->w_vsep_width = 0;
|
wp->w_vsep_width = 0;
|
||||||
|
|
||||||
redraw_all_later(NOT_VALID);
|
redraw_all_later(NOT_VALID);
|
||||||
|
popup_mask_refresh = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -815,6 +835,7 @@ f_popup_hide(typval_T *argvars, typval_T *rettv UNUSED)
|
|||||||
wp->w_popup_flags |= POPF_HIDDEN;
|
wp->w_popup_flags |= POPF_HIDDEN;
|
||||||
--wp->w_buffer->b_nwindows;
|
--wp->w_buffer->b_nwindows;
|
||||||
redraw_all_later(NOT_VALID);
|
redraw_all_later(NOT_VALID);
|
||||||
|
popup_mask_refresh = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -832,6 +853,7 @@ f_popup_show(typval_T *argvars, typval_T *rettv UNUSED)
|
|||||||
wp->w_popup_flags &= ~POPF_HIDDEN;
|
wp->w_popup_flags &= ~POPF_HIDDEN;
|
||||||
++wp->w_buffer->b_nwindows;
|
++wp->w_buffer->b_nwindows;
|
||||||
redraw_all_later(NOT_VALID);
|
redraw_all_later(NOT_VALID);
|
||||||
|
popup_mask_refresh = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -843,6 +865,7 @@ popup_free(win_T *wp)
|
|||||||
clear_cmdline = TRUE;
|
clear_cmdline = TRUE;
|
||||||
win_free_popup(wp);
|
win_free_popup(wp);
|
||||||
redraw_all_later(NOT_VALID);
|
redraw_all_later(NOT_VALID);
|
||||||
|
popup_mask_refresh = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -944,7 +967,6 @@ f_popup_move(typval_T *argvars, typval_T *rettv UNUSED)
|
|||||||
if (wp->w_winrow + wp->w_height >= cmdline_row)
|
if (wp->w_winrow + wp->w_height >= cmdline_row)
|
||||||
clear_cmdline = TRUE;
|
clear_cmdline = TRUE;
|
||||||
popup_adjust_position(wp);
|
popup_adjust_position(wp);
|
||||||
redraw_all_later(NOT_VALID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -984,7 +1006,7 @@ f_popup_getpos(typval_T *argvars, typval_T *rettv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* f_popup_getoptions({id})
|
* popup_getoptions({id})
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
f_popup_getoptions(typval_T *argvars, typval_T *rettv)
|
f_popup_getoptions(typval_T *argvars, typval_T *rettv)
|
||||||
|
@ -16,6 +16,7 @@ int update_screen(int type_arg);
|
|||||||
int conceal_cursor_line(win_T *wp);
|
int conceal_cursor_line(win_T *wp);
|
||||||
void conceal_check_cursor_line(void);
|
void conceal_check_cursor_line(void);
|
||||||
void update_debug_sign(buf_T *buf, linenr_T lnum);
|
void update_debug_sign(buf_T *buf, linenr_T lnum);
|
||||||
|
int may_update_popup_mask(int type_arg);
|
||||||
void updateWindow(win_T *wp);
|
void updateWindow(win_T *wp);
|
||||||
int screen_get_current_line_off(void);
|
int screen_get_current_line_off(void);
|
||||||
void screen_line(int row, int coloff, int endcol, int clear_width, int flags);
|
void screen_line(int row, int coloff, int endcol, int clear_width, int flags);
|
||||||
|
214
src/screen.c
214
src/screen.c
@ -610,15 +610,10 @@ update_screen(int type_arg)
|
|||||||
curwin->w_lines_valid = 0; /* don't use w_lines[].wl_size now */
|
curwin->w_lines_valid = 0; /* don't use w_lines[].wl_size now */
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FEAT_TEXT_PROP
|
#ifdef FEAT_TEXT_PROP
|
||||||
// TODO: avoid redrawing everything when there is a popup window.
|
// Update popup_mask if needed.
|
||||||
if (popup_any_visible())
|
type = may_update_popup_mask(type);
|
||||||
{
|
|
||||||
if (type < NOT_VALID)
|
|
||||||
type = NOT_VALID;
|
|
||||||
FOR_ALL_WINDOWS(wp)
|
|
||||||
wp->w_redr_type = NOT_VALID;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
updating_screen = TRUE;
|
updating_screen = TRUE;
|
||||||
@ -880,6 +875,10 @@ update_prepare(void)
|
|||||||
#ifdef FEAT_SEARCH_EXTRA
|
#ifdef FEAT_SEARCH_EXTRA
|
||||||
start_search_hl();
|
start_search_hl();
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
// Update popup_mask if needed.
|
||||||
|
may_update_popup_mask(0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -992,11 +991,6 @@ update_debug_sign(buf_T *buf, linenr_T lnum)
|
|||||||
win_redr_status(wp, FALSE);
|
win_redr_status(wp, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FEAT_TEXT_PROP
|
|
||||||
// Display popup windows on top of the others.
|
|
||||||
update_popups();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
update_finish();
|
update_finish();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1020,6 +1014,82 @@ get_wcr_attr(win_T *wp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FEAT_TEXT_PROP
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
/*
|
||||||
|
* Update "popup_mask" if needed.
|
||||||
|
* Also recomputes the popup size and positions.
|
||||||
|
* Also updates "popup_visible".
|
||||||
|
* If more redrawing is needed than "type_arg" a higher value is returned.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
may_update_popup_mask(int type_arg)
|
||||||
|
{
|
||||||
|
int type = type_arg;
|
||||||
|
win_T *wp;
|
||||||
|
|
||||||
|
if (popup_mask_tab != curtab)
|
||||||
|
popup_mask_refresh = TRUE;
|
||||||
|
if (!popup_mask_refresh)
|
||||||
|
{
|
||||||
|
// Check if any buffer has changed.
|
||||||
|
for (wp = first_popupwin; wp != NULL; wp = wp->w_next)
|
||||||
|
if (wp->w_popup_last_changedtick != CHANGEDTICK(wp->w_buffer))
|
||||||
|
popup_mask_refresh = TRUE;
|
||||||
|
for (wp = curtab->tp_first_popupwin; wp != NULL; wp = wp->w_next)
|
||||||
|
if (wp->w_popup_last_changedtick != CHANGEDTICK(wp->w_buffer))
|
||||||
|
popup_mask_refresh = TRUE;
|
||||||
|
if (!popup_mask_refresh)
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
popup_mask_refresh = FALSE;
|
||||||
|
popup_mask_tab = curtab;
|
||||||
|
|
||||||
|
popup_visible = FALSE;
|
||||||
|
vim_memset(popup_mask, 0, screen_Rows * screen_Columns * sizeof(short));
|
||||||
|
|
||||||
|
// Find the window with the lowest zindex that hasn't been handled yet,
|
||||||
|
// so that the window with a higher zindex overwrites the value in
|
||||||
|
// popup_mask.
|
||||||
|
popup_reset_handled();
|
||||||
|
while ((wp = find_next_popup(TRUE)) != NULL)
|
||||||
|
{
|
||||||
|
int top_off, bot_off;
|
||||||
|
int left_off, right_off;
|
||||||
|
short *p;
|
||||||
|
int line, col;
|
||||||
|
|
||||||
|
popup_visible = TRUE;
|
||||||
|
|
||||||
|
// Recompute the position if the text changed.
|
||||||
|
if (wp->w_popup_last_changedtick != CHANGEDTICK(wp->w_buffer))
|
||||||
|
popup_adjust_position(wp);
|
||||||
|
|
||||||
|
// the position and size are for the inside, add the padding and
|
||||||
|
// border
|
||||||
|
top_off = wp->w_popup_padding[0] + wp->w_popup_border[0];
|
||||||
|
bot_off = wp->w_popup_padding[2] + wp->w_popup_border[2];
|
||||||
|
left_off = wp->w_popup_padding[3] + wp->w_popup_border[3];
|
||||||
|
right_off = wp->w_popup_padding[1] + wp->w_popup_border[1];
|
||||||
|
|
||||||
|
for (line = wp->w_winrow + top_off;
|
||||||
|
line < wp->w_winrow + wp->w_height + bot_off
|
||||||
|
&& line < screen_Rows; ++line)
|
||||||
|
for (col = wp->w_wincol + left_off;
|
||||||
|
col < wp->w_wincol + wp->w_width + right_off
|
||||||
|
&& col < screen_Columns; ++col)
|
||||||
|
{
|
||||||
|
p = popup_mask + line * screen_Columns + col;
|
||||||
|
if (*p != wp->w_zindex)
|
||||||
|
{
|
||||||
|
*p = wp->w_zindex;
|
||||||
|
type = NOT_VALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return a string of "len" spaces in IObuff.
|
* Return a string of "len" spaces in IObuff.
|
||||||
*/
|
*/
|
||||||
@ -1049,14 +1119,13 @@ update_popups(void)
|
|||||||
// Find the window with the lowest zindex that hasn't been updated yet,
|
// Find the window with the lowest zindex that hasn't been updated yet,
|
||||||
// so that the window with a higher zindex is drawn later, thus goes on
|
// so that the window with a higher zindex is drawn later, thus goes on
|
||||||
// top.
|
// top.
|
||||||
// TODO: don't redraw every popup every time.
|
|
||||||
popup_visible = FALSE;
|
|
||||||
popup_reset_handled();
|
popup_reset_handled();
|
||||||
while ((wp = find_next_popup(TRUE)) != NULL)
|
while ((wp = find_next_popup(TRUE)) != NULL)
|
||||||
{
|
{
|
||||||
// Recompute the position if the text changed.
|
// This drawing uses the zindex of the popup window, so that it's on
|
||||||
if (wp->w_popup_last_changedtick != CHANGEDTICK(wp->w_buffer))
|
// top of the text but doesn't draw when another popup with higher
|
||||||
popup_adjust_position(wp);
|
// zindex is on top of the character.
|
||||||
|
screen_zindex = wp->w_zindex;
|
||||||
|
|
||||||
// adjust w_winrow and w_wincol for border and padding, since
|
// adjust w_winrow and w_wincol for border and padding, since
|
||||||
// win_update() doesn't handle them.
|
// win_update() doesn't handle them.
|
||||||
@ -1067,7 +1136,6 @@ update_popups(void)
|
|||||||
|
|
||||||
// Draw the popup text.
|
// Draw the popup text.
|
||||||
win_update(wp);
|
win_update(wp);
|
||||||
popup_visible = TRUE;
|
|
||||||
|
|
||||||
wp->w_winrow -= top_off;
|
wp->w_winrow -= top_off;
|
||||||
wp->w_wincol -= left_off;
|
wp->w_wincol -= left_off;
|
||||||
@ -1190,6 +1258,9 @@ update_popups(void)
|
|||||||
wp->w_wincol + total_width - 1, border_attr[2]);
|
wp->w_wincol + total_width - 1, border_attr[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Back to the normal zindex.
|
||||||
|
screen_zindex = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -6477,6 +6548,11 @@ screen_line(
|
|||||||
redraw_this = TRUE;
|
redraw_this = TRUE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
// Skip if under a(nother) popup.
|
||||||
|
if (popup_mask[row * screen_Columns + col + coloff] > screen_zindex)
|
||||||
|
redraw_this = FALSE;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (redraw_this)
|
if (redraw_this)
|
||||||
{
|
{
|
||||||
@ -6721,6 +6797,7 @@ screen_line(
|
|||||||
if (clear_width > 0
|
if (clear_width > 0
|
||||||
#ifdef FEAT_TEXT_PROP
|
#ifdef FEAT_TEXT_PROP
|
||||||
&& !(flags & SLF_POPUP) // no separator for popup window
|
&& !(flags & SLF_POPUP) // no separator for popup window
|
||||||
|
&& popup_mask[row * screen_Columns + col + coloff] <= screen_zindex
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -6821,11 +6898,6 @@ redraw_statuslines(void)
|
|||||||
win_redr_status(wp, FALSE);
|
win_redr_status(wp, FALSE);
|
||||||
if (redraw_tabline)
|
if (redraw_tabline)
|
||||||
draw_tabline();
|
draw_tabline();
|
||||||
|
|
||||||
#ifdef FEAT_TEXT_PROP
|
|
||||||
// Display popup windows on top of the status lines.
|
|
||||||
update_popups();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(FEAT_WILDMENU) || defined(PROTO)
|
#if defined(FEAT_WILDMENU) || defined(PROTO)
|
||||||
@ -8577,9 +8649,21 @@ screen_char(unsigned off, int row, int col)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef FEAT_INS_EXPAND
|
#ifdef FEAT_INS_EXPAND
|
||||||
if (pum_under_menu(row, col))
|
// Skip if under the popup menu.
|
||||||
|
// Popup windows with zindex higher than POPUPMENU_ZINDEX go on top.
|
||||||
|
if (pum_under_menu(row, col)
|
||||||
|
# ifdef FEAT_TEXT_PROP
|
||||||
|
&& screen_zindex <= POPUPMENU_ZINDEX
|
||||||
|
# endif
|
||||||
|
)
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
// Skip if under a(nother) popup.
|
||||||
|
if (popup_mask[row * screen_Columns + col] > screen_zindex)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Outputting a character in the last cell on the screen may scroll the
|
/* Outputting a character in the last cell on the screen may scroll the
|
||||||
* screen up. Only do it when the "xn" termcap property is set, otherwise
|
* screen up. Only do it when the "xn" termcap property is set, otherwise
|
||||||
* mark the character invalid (update it when scrolled up). */
|
* mark the character invalid (update it when scrolled up). */
|
||||||
@ -8869,7 +8953,7 @@ screen_fill(
|
|||||||
c = c1;
|
c = c1;
|
||||||
for (col = start_col; col < end_col; ++col)
|
for (col = start_col; col < end_col; ++col)
|
||||||
{
|
{
|
||||||
if (ScreenLines[off] != c
|
if ((ScreenLines[off] != c
|
||||||
|| (enc_utf8 && (int)ScreenLinesUC[off]
|
|| (enc_utf8 && (int)ScreenLinesUC[off]
|
||||||
!= (c >= 0x80 ? c : 0))
|
!= (c >= 0x80 ? c : 0))
|
||||||
|| ScreenAttrs[off] != attr
|
|| ScreenAttrs[off] != attr
|
||||||
@ -8877,6 +8961,11 @@ screen_fill(
|
|||||||
|| force_next
|
|| force_next
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
// Skip if under a(nother) popup.
|
||||||
|
&& popup_mask[row * screen_Columns + col] <= screen_zindex
|
||||||
|
#endif
|
||||||
|
)
|
||||||
{
|
{
|
||||||
#if defined(FEAT_GUI) || defined(UNIX)
|
#if defined(FEAT_GUI) || defined(UNIX)
|
||||||
/* The bold trick may make a single row of pixels appear in
|
/* The bold trick may make a single row of pixels appear in
|
||||||
@ -9013,6 +9102,9 @@ screenalloc(int doclear)
|
|||||||
unsigned *new_LineOffset;
|
unsigned *new_LineOffset;
|
||||||
char_u *new_LineWraps;
|
char_u *new_LineWraps;
|
||||||
short *new_TabPageIdxs;
|
short *new_TabPageIdxs;
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
short *new_popup_mask;
|
||||||
|
#endif
|
||||||
tabpage_T *tp;
|
tabpage_T *tp;
|
||||||
static int entered = FALSE; /* avoid recursiveness */
|
static int entered = FALSE; /* avoid recursiveness */
|
||||||
static int done_outofmem_msg = FALSE; /* did outofmem message */
|
static int done_outofmem_msg = FALSE; /* did outofmem message */
|
||||||
@ -9094,6 +9186,9 @@ retry:
|
|||||||
new_LineOffset = LALLOC_MULT(unsigned, Rows);
|
new_LineOffset = LALLOC_MULT(unsigned, Rows);
|
||||||
new_LineWraps = LALLOC_MULT(char_u, Rows);
|
new_LineWraps = LALLOC_MULT(char_u, Rows);
|
||||||
new_TabPageIdxs = LALLOC_MULT(short, Columns);
|
new_TabPageIdxs = LALLOC_MULT(short, Columns);
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
new_popup_mask = LALLOC_MULT(short, Rows * Columns);
|
||||||
|
#endif
|
||||||
|
|
||||||
FOR_ALL_TAB_WINDOWS(tp, wp)
|
FOR_ALL_TAB_WINDOWS(tp, wp)
|
||||||
{
|
{
|
||||||
@ -9136,6 +9231,9 @@ give_up:
|
|||||||
|| new_LineOffset == NULL
|
|| new_LineOffset == NULL
|
||||||
|| new_LineWraps == NULL
|
|| new_LineWraps == NULL
|
||||||
|| new_TabPageIdxs == NULL
|
|| new_TabPageIdxs == NULL
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
|| new_popup_mask == NULL
|
||||||
|
#endif
|
||||||
|| outofmem)
|
|| outofmem)
|
||||||
{
|
{
|
||||||
if (ScreenLines != NULL || !done_outofmem_msg)
|
if (ScreenLines != NULL || !done_outofmem_msg)
|
||||||
@ -9156,6 +9254,9 @@ give_up:
|
|||||||
VIM_CLEAR(new_LineOffset);
|
VIM_CLEAR(new_LineOffset);
|
||||||
VIM_CLEAR(new_LineWraps);
|
VIM_CLEAR(new_LineWraps);
|
||||||
VIM_CLEAR(new_TabPageIdxs);
|
VIM_CLEAR(new_TabPageIdxs);
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
VIM_CLEAR(new_popup_mask);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -9242,6 +9343,11 @@ give_up:
|
|||||||
LineOffset = new_LineOffset;
|
LineOffset = new_LineOffset;
|
||||||
LineWraps = new_LineWraps;
|
LineWraps = new_LineWraps;
|
||||||
TabPageIdxs = new_TabPageIdxs;
|
TabPageIdxs = new_TabPageIdxs;
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
popup_mask = new_popup_mask;
|
||||||
|
vim_memset(popup_mask, 0, screen_Rows * screen_Columns * sizeof(short));
|
||||||
|
popup_mask_refresh = TRUE;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* It's important that screen_Rows and screen_Columns reflect the actual
|
/* It's important that screen_Rows and screen_Columns reflect the actual
|
||||||
* size of ScreenLines[]. Set them before calling anything. */
|
* size of ScreenLines[]. Set them before calling anything. */
|
||||||
@ -9296,15 +9402,18 @@ free_screenlines(void)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
vim_free(ScreenLinesUC);
|
VIM_CLEAR(ScreenLinesUC);
|
||||||
for (i = 0; i < Screen_mco; ++i)
|
for (i = 0; i < Screen_mco; ++i)
|
||||||
vim_free(ScreenLinesC[i]);
|
VIM_CLEAR(ScreenLinesC[i]);
|
||||||
vim_free(ScreenLines2);
|
VIM_CLEAR(ScreenLines2);
|
||||||
vim_free(ScreenLines);
|
VIM_CLEAR(ScreenLines);
|
||||||
vim_free(ScreenAttrs);
|
VIM_CLEAR(ScreenAttrs);
|
||||||
vim_free(LineOffset);
|
VIM_CLEAR(LineOffset);
|
||||||
vim_free(LineWraps);
|
VIM_CLEAR(LineWraps);
|
||||||
vim_free(TabPageIdxs);
|
VIM_CLEAR(TabPageIdxs);
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
VIM_CLEAR(popup_mask);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -9429,6 +9538,7 @@ linecopy(int to, int from, win_T *wp)
|
|||||||
/*
|
/*
|
||||||
* Return TRUE if clearing with term string "p" would work.
|
* Return TRUE if clearing with term string "p" would work.
|
||||||
* It can't work when the string is empty or it won't set the right background.
|
* It can't work when the string is empty or it won't set the right background.
|
||||||
|
* Don't clear to end-of-line when there are popups, it may cause flicker.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
can_clear(char_u *p)
|
can_clear(char_u *p)
|
||||||
@ -9443,7 +9553,11 @@ can_clear(char_u *p)
|
|||||||
#else
|
#else
|
||||||
|| cterm_normal_bg_color == 0
|
|| cterm_normal_bg_color == 0
|
||||||
#endif
|
#endif
|
||||||
|| *T_UT != NUL));
|
|| *T_UT != NUL)
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
&& !(p == T_CE && popup_visible)
|
||||||
|
#endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -9891,22 +10005,26 @@ win_do_lines(
|
|||||||
if (!redrawing() || line_count <= 0)
|
if (!redrawing() || line_count <= 0)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
|
||||||
/* When inserting lines would result in loss of command output, just redraw
|
// When inserting lines would result in loss of command output, just redraw
|
||||||
* the lines. */
|
// the lines.
|
||||||
if (no_win_do_lines_ins && !del)
|
if (no_win_do_lines_ins && !del)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
|
||||||
/* only a few lines left: redraw is faster */
|
// only a few lines left: redraw is faster
|
||||||
if (mayclear && Rows - line_count < 5 && wp->w_width == Columns)
|
if (mayclear && Rows - line_count < 5 && wp->w_width == Columns)
|
||||||
{
|
{
|
||||||
if (!no_win_do_lines_ins)
|
if (!no_win_do_lines_ins)
|
||||||
screenclear(); /* will set wp->w_lines_valid to 0 */
|
screenclear(); // will set wp->w_lines_valid to 0
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
#ifdef FEAT_TEXT_PROP
|
||||||
* Delete all remaining lines
|
// this doesn't work when tere are popups visible
|
||||||
*/
|
if (popup_visible)
|
||||||
|
return FAIL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Delete all remaining lines
|
||||||
if (row + line_count >= wp->w_height)
|
if (row + line_count >= wp->w_height)
|
||||||
{
|
{
|
||||||
screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + wp->w_height,
|
screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + wp->w_height,
|
||||||
@ -10024,11 +10142,16 @@ screen_ins_lines(
|
|||||||
* - the line count is less than one
|
* - the line count is less than one
|
||||||
* - the line count is more than 'ttyscroll'
|
* - the line count is more than 'ttyscroll'
|
||||||
* - redrawing for a callback and there is a modeless selection
|
* - redrawing for a callback and there is a modeless selection
|
||||||
|
* - there is a popup window
|
||||||
*/
|
*/
|
||||||
if (!screen_valid(TRUE) || line_count <= 0 || line_count > p_ttyscroll
|
if (!screen_valid(TRUE)
|
||||||
|
|| line_count <= 0 || line_count > p_ttyscroll
|
||||||
#ifdef FEAT_CLIPBOARD
|
#ifdef FEAT_CLIPBOARD
|
||||||
|| (clip_star.state != SELECT_CLEARED
|
|| (clip_star.state != SELECT_CLEARED
|
||||||
&& redrawing_for_callback > 0)
|
&& redrawing_for_callback > 0)
|
||||||
|
#endif
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
|| popup_visible
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
@ -11136,11 +11259,6 @@ showruler(int always)
|
|||||||
/* Redraw the tab pages line if needed. */
|
/* Redraw the tab pages line if needed. */
|
||||||
if (redraw_tabline)
|
if (redraw_tabline)
|
||||||
draw_tabline();
|
draw_tabline();
|
||||||
|
|
||||||
#ifdef FEAT_TEXT_PROP
|
|
||||||
// Display popup windows on top of everything.
|
|
||||||
update_popups();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FEAT_CMDL_INFO
|
#ifdef FEAT_CMDL_INFO
|
||||||
|
@ -767,6 +767,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1493,
|
||||||
/**/
|
/**/
|
||||||
1492,
|
1492,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user