mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 18:55:14 -07:00
vim-patch:9.0.0245: mechanism to prevent recursive screen updating is incomplete (#27448)
Problem: Mechanism to prevent recursive screen updating is incomplete.
Solution: Add "redraw_not_allowed" and set it in build_stl_str_hl().
(issue vim/vim#10952)
471c0fa3ee
Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
parent
84b6ade415
commit
984f7a9fd3
@ -322,7 +322,7 @@ static void changed_common(buf_T *buf, linenr_T lnum, colnr_T col, linenr_T lnum
|
||||
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
||||
if (wp->w_buffer == buf) {
|
||||
// Mark this window to be redrawn later.
|
||||
if (wp->w_redr_type < UPD_VALID) {
|
||||
if (!redraw_not_allowed && wp->w_redr_type < UPD_VALID) {
|
||||
wp->w_redr_type = UPD_VALID;
|
||||
}
|
||||
|
||||
@ -390,9 +390,7 @@ static void changed_common(buf_T *buf, linenr_T lnum, colnr_T col, linenr_T lnum
|
||||
|
||||
// Call update_screen() later, which checks out what needs to be redrawn,
|
||||
// since it notices b_mod_set and then uses b_mod_*.
|
||||
if (must_redraw < UPD_VALID) {
|
||||
must_redraw = UPD_VALID;
|
||||
}
|
||||
set_must_redraw(UPD_VALID);
|
||||
|
||||
// when the cursor line is changed always trigger CursorMoved
|
||||
if (last_cursormoved_win == curwin && curwin->w_buffer == buf
|
||||
|
@ -2647,7 +2647,7 @@ void redraw_later(win_T *wp, int type)
|
||||
{
|
||||
// curwin may have been set to NULL when exiting
|
||||
assert(wp != NULL || exiting);
|
||||
if (!exiting && wp->w_redr_type < type) {
|
||||
if (!exiting && !redraw_not_allowed && wp->w_redr_type < type) {
|
||||
wp->w_redr_type = type;
|
||||
if (type >= UPD_NOT_VALID) {
|
||||
wp->w_lines_valid = 0;
|
||||
@ -2665,7 +2665,14 @@ void redraw_all_later(int type)
|
||||
redraw_later(wp, type);
|
||||
}
|
||||
// This may be needed when switching tabs.
|
||||
if (must_redraw < type) {
|
||||
set_must_redraw(type);
|
||||
}
|
||||
|
||||
/// Set "must_redraw" to "type" unless it already has a higher value
|
||||
/// or it is currently not allowed.
|
||||
void set_must_redraw(int type)
|
||||
{
|
||||
if (!redraw_not_allowed && must_redraw < type) {
|
||||
must_redraw = type;
|
||||
}
|
||||
}
|
||||
@ -2730,9 +2737,7 @@ void redraw_buf_status_later(buf_T *buf)
|
||||
|| (wp == curwin && global_stl_height())
|
||||
|| wp->w_winbar_height)) {
|
||||
wp->w_redr_status = true;
|
||||
if (must_redraw < UPD_VALID) {
|
||||
must_redraw = UPD_VALID;
|
||||
}
|
||||
set_must_redraw(UPD_VALID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,10 @@ enum {
|
||||
/// ('lines' and 'rows') must not be changed.
|
||||
EXTERN bool updating_screen INIT( = false);
|
||||
|
||||
/// While computing a statusline and the like we do not want any w_redr_type or
|
||||
/// must_redraw to be set.
|
||||
EXTERN bool redraw_not_allowed INIT( = false);
|
||||
|
||||
EXTERN match_T screen_search_hl INIT( = { 0 }); ///< used for 'hlsearch' highlight matching
|
||||
|
||||
#define W_ENDCOL(wp) ((wp)->w_wincol + (wp)->w_width)
|
||||
|
@ -902,9 +902,7 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear
|
||||
// not get printed in the middle of it.
|
||||
msg_check();
|
||||
if (p_ch == 0 && !ui_has(kUIMessages)) {
|
||||
if (must_redraw < UPD_VALID) {
|
||||
must_redraw = UPD_VALID;
|
||||
}
|
||||
set_must_redraw(UPD_VALID);
|
||||
}
|
||||
msg_scroll = s->save_msg_scroll;
|
||||
redir_off = false;
|
||||
|
@ -2419,9 +2419,7 @@ static void inc_msg_scrolled(void)
|
||||
xfree(tofree);
|
||||
}
|
||||
msg_scrolled++;
|
||||
if (must_redraw < UPD_VALID) {
|
||||
must_redraw = UPD_VALID;
|
||||
}
|
||||
set_must_redraw(UPD_VALID);
|
||||
}
|
||||
|
||||
static msgchunk_T *last_msgchunk = NULL; // last displayed text
|
||||
@ -3067,9 +3065,7 @@ void msg_ext_clear_later(void)
|
||||
{
|
||||
if (msg_ext_is_visible()) {
|
||||
msg_ext_need_clear = true;
|
||||
if (must_redraw < UPD_VALID) {
|
||||
must_redraw = UPD_VALID;
|
||||
}
|
||||
set_must_redraw(UPD_VALID);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -935,14 +935,20 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
|
||||
char buf_tmp[TMPLEN];
|
||||
char win_tmp[TMPLEN];
|
||||
char *usefmt = fmt;
|
||||
const int save_must_redraw = must_redraw;
|
||||
const int save_redr_type = curwin->w_redr_type;
|
||||
const bool save_redraw_not_allowed = redraw_not_allowed;
|
||||
const bool save_KeyTyped = KeyTyped;
|
||||
// TODO(Bram): find out why using called_emsg_before makes tests fail, does it
|
||||
// matter?
|
||||
// const int called_emsg_before = called_emsg;
|
||||
const int did_emsg_before = did_emsg;
|
||||
|
||||
// When inside update_screen() we do not want redrawing a statusline,
|
||||
// ruler, title, etc. to trigger another redraw, it may cause an endless
|
||||
// loop.
|
||||
if (updating_screen) {
|
||||
redraw_not_allowed = true;
|
||||
}
|
||||
|
||||
if (stl_items == NULL) {
|
||||
stl_items = xmalloc(sizeof(stl_item_t) * stl_items_len);
|
||||
stl_groupitems = xmalloc(sizeof(int) * stl_items_len);
|
||||
@ -1938,16 +1944,16 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
|
||||
stl_items[curitem].type = Empty;
|
||||
}
|
||||
|
||||
if (num >= 0 || (!itemisflag && str && *str)) {
|
||||
prevchar_isflag = false; // Item not NULL, but not a flag
|
||||
}
|
||||
|
||||
// Only free the string buffer if we allocated it.
|
||||
// Note: This is not needed if `str` is pointing at `tmp`
|
||||
if (opt == STL_VIM_EXPR) {
|
||||
XFREE_CLEAR(str);
|
||||
}
|
||||
|
||||
if (num >= 0 || (!itemisflag && str && *str)) {
|
||||
prevchar_isflag = false; // Item not NULL, but not a flag
|
||||
}
|
||||
|
||||
// Item processed, move to the next
|
||||
curitem++;
|
||||
}
|
||||
@ -2172,12 +2178,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
|
||||
cur_tab_rec->def.func = NULL;
|
||||
}
|
||||
|
||||
// When inside update_screen we do not want redrawing a statusline, ruler,
|
||||
// title, etc. to trigger another redraw, it may cause an endless loop.
|
||||
if (updating_screen) {
|
||||
must_redraw = save_must_redraw;
|
||||
curwin->w_redr_type = save_redr_type;
|
||||
}
|
||||
redraw_not_allowed = save_redraw_not_allowed;
|
||||
|
||||
// Check for an error. If there is one the display will be messed up and
|
||||
// might loop redrawing. Avoid that by making the corresponding option
|
||||
|
@ -184,7 +184,7 @@ void win_config_float(win_T *wp, WinConfig fconfig)
|
||||
}
|
||||
|
||||
win_set_inner_size(wp, true);
|
||||
must_redraw = MAX(must_redraw, UPD_VALID);
|
||||
set_must_redraw(UPD_VALID);
|
||||
|
||||
wp->w_pos_changed = true;
|
||||
if (change_external || change_border) {
|
||||
|
Loading…
Reference in New Issue
Block a user