mirror of
https://github.com/neovim/neovim.git
synced 2025-10-16 14:56:08 +00:00
fix(redraw): avoid unnecessary redraws and glitches with floats+messages
fixes #20106 fixes #20229
This commit is contained in:
@@ -1445,7 +1445,6 @@ win_found:
|
||||
}
|
||||
|
||||
aucmd_win_used = false;
|
||||
last_status(false); // may need to remove last status line
|
||||
|
||||
if (!valid_tabpage_win(curtab)) {
|
||||
// no valid window in current tabpage
|
||||
|
@@ -389,6 +389,10 @@ int update_screen(int type)
|
||||
diff_redraw(true);
|
||||
}
|
||||
|
||||
// TODO(bfredl): completely get rid of using update_screen(UPD_XX_VALID)
|
||||
// to redraw curwin
|
||||
int curwin_type = MIN(type, UPD_NOT_VALID);
|
||||
|
||||
if (must_redraw) {
|
||||
if (type < must_redraw) { // use maximal type
|
||||
type = must_redraw;
|
||||
@@ -445,9 +449,11 @@ int update_screen(int type)
|
||||
}
|
||||
if (msg_use_msgsep()) {
|
||||
msg_grid.throttled = false;
|
||||
bool was_invalidated = false;
|
||||
|
||||
// UPD_CLEAR is already handled
|
||||
if (type == UPD_NOT_VALID && !ui_has(kUIMultigrid) && msg_scrolled) {
|
||||
ui_comp_set_screen_valid(false);
|
||||
was_invalidated = ui_comp_set_screen_valid(false);
|
||||
for (int i = valid; i < Rows - p_ch; i++) {
|
||||
grid_clear_line(&default_grid, default_grid.line_offset[i],
|
||||
Columns, false);
|
||||
@@ -457,6 +463,8 @@ int update_screen(int type)
|
||||
continue;
|
||||
}
|
||||
if (W_ENDROW(wp) > valid) {
|
||||
// TODO(bfredl): too pessimistic. type could be UPD_NOT_VALID
|
||||
// only because windows that are above the separator.
|
||||
wp->w_redr_type = MAX(wp->w_redr_type, UPD_NOT_VALID);
|
||||
}
|
||||
if (!is_stl_global && W_ENDROW(wp) + wp->w_status_height > valid) {
|
||||
@@ -469,9 +477,16 @@ int update_screen(int type)
|
||||
}
|
||||
msg_grid_set_pos(Rows - (int)p_ch, false);
|
||||
msg_grid_invalid = false;
|
||||
if (was_invalidated) {
|
||||
// screen was only invalid for the msgarea part.
|
||||
// @TODO(bfredl): using the same "valid" flag
|
||||
// for both messages and floats moving is bit of a mess.
|
||||
ui_comp_set_screen_valid(true);
|
||||
}
|
||||
} else if (type != UPD_CLEAR) {
|
||||
if (msg_scrolled > Rows - 5) { // redrawing is faster
|
||||
type = UPD_NOT_VALID;
|
||||
curwin_type = UPD_NOT_VALID;
|
||||
} else {
|
||||
check_for_delay(false);
|
||||
grid_ins_lines(&default_grid, 0, msg_scrolled, Rows, 0, Columns);
|
||||
@@ -506,7 +521,7 @@ int update_screen(int type)
|
||||
need_wait_return = false;
|
||||
}
|
||||
|
||||
win_ui_flush();
|
||||
win_ui_flush(true);
|
||||
msg_ext_check_clear();
|
||||
|
||||
// reset cmdline_row now (may have been changed temporarily)
|
||||
@@ -553,6 +568,8 @@ int update_screen(int type)
|
||||
|
||||
// Force redraw when width of 'number' or 'relativenumber' column
|
||||
// changes.
|
||||
// TODO(bfredl): special casing curwin here is SÅ JÄVLA BULL.
|
||||
// Either this should be done for all windows or not at all.
|
||||
if (curwin->w_redr_type < UPD_NOT_VALID
|
||||
&& curwin->w_nrwidth != ((curwin->w_p_nu || curwin->w_p_rnu)
|
||||
? number_width(curwin) : 0)) {
|
||||
@@ -560,22 +577,25 @@ int update_screen(int type)
|
||||
}
|
||||
|
||||
// Only start redrawing if there is really something to do.
|
||||
if (type == UPD_INVERTED) {
|
||||
// TODO(bfredl): more curwin special casing to get rid of.
|
||||
// Change update_screen(UPD_INVERTED) to a wrapper function
|
||||
// perhaps?
|
||||
if (curwin_type == UPD_INVERTED) {
|
||||
update_curswant();
|
||||
}
|
||||
if (curwin->w_redr_type < type
|
||||
&& !((type == UPD_VALID
|
||||
if (curwin->w_redr_type < curwin_type
|
||||
&& !((curwin_type == UPD_VALID
|
||||
&& curwin->w_lines[0].wl_valid
|
||||
&& curwin->w_topfill == curwin->w_old_topfill
|
||||
&& curwin->w_botfill == curwin->w_old_botfill
|
||||
&& curwin->w_topline == curwin->w_lines[0].wl_lnum)
|
||||
|| (type == UPD_INVERTED
|
||||
|| (curwin_type == UPD_INVERTED
|
||||
&& VIsual_active
|
||||
&& curwin->w_old_cursor_lnum == curwin->w_cursor.lnum
|
||||
&& curwin->w_old_visual_mode == VIsual_mode
|
||||
&& (curwin->w_valid & VALID_VIRTCOL)
|
||||
&& curwin->w_old_curswant == curwin->w_curswant))) {
|
||||
curwin->w_redr_type = type;
|
||||
curwin->w_redr_type = curwin_type;
|
||||
}
|
||||
|
||||
// Redraw the tab pages line if needed.
|
||||
@@ -1022,7 +1042,9 @@ win_update_start:
|
||||
type = wp->w_redr_type;
|
||||
|
||||
if (type >= UPD_NOT_VALID) {
|
||||
// TODO(bfredl): should only be implied for CLEAR, not NOT_VALID!
|
||||
wp->w_redr_status = true;
|
||||
|
||||
wp->w_lines_valid = 0;
|
||||
}
|
||||
|
||||
|
@@ -1658,7 +1658,7 @@ void ex_luado(exarg_T *const eap)
|
||||
}
|
||||
lua_pop(lstate, 1);
|
||||
check_cursor();
|
||||
update_screen(UPD_NOT_VALID);
|
||||
redraw_curbuf_later(UPD_NOT_VALID);
|
||||
}
|
||||
|
||||
/// Run lua file
|
||||
|
@@ -2053,7 +2053,7 @@ void msg_puts_attr_len(const char *const str, const ptrdiff_t len, int attr)
|
||||
overflow = true;
|
||||
}
|
||||
} else {
|
||||
overflow = msg_scrolled != 0;
|
||||
overflow = msg_scrolled > (p_ch == 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
if (overflow && !msg_scrolled_ign && strcmp(str, "\r") != 0) {
|
||||
@@ -2334,7 +2334,7 @@ bool message_filtered(char *msg)
|
||||
/// including horizontal separator
|
||||
int msg_scrollsize(void)
|
||||
{
|
||||
return msg_scrolled + (int)p_ch + 1;
|
||||
return msg_scrolled + (int)p_ch + ((p_ch > 0 || msg_scrolled > 1) ? 1 : 0);
|
||||
}
|
||||
|
||||
bool msg_use_msgsep(void)
|
||||
|
@@ -510,7 +510,7 @@ void ui_flush(void)
|
||||
return;
|
||||
}
|
||||
cmdline_ui_flush();
|
||||
win_ui_flush();
|
||||
win_ui_flush(false);
|
||||
msg_ext_ui_flush();
|
||||
msg_scroll_flush();
|
||||
|
||||
|
@@ -590,12 +590,14 @@ static void ui_comp_raw_line(UI *ui, Integer grid, Integer row, Integer startcol
|
||||
/// The screen is invalid and will soon be cleared
|
||||
///
|
||||
/// Don't redraw floats until screen is cleared
|
||||
void ui_comp_set_screen_valid(bool valid)
|
||||
bool ui_comp_set_screen_valid(bool valid)
|
||||
{
|
||||
bool old_val = valid_screen;
|
||||
valid_screen = valid;
|
||||
if (!valid) {
|
||||
msg_sep_row = -1;
|
||||
}
|
||||
return old_val;
|
||||
}
|
||||
|
||||
static void ui_comp_msg_set_pos(UI *ui, Integer grid, Integer row, Boolean scrolled,
|
||||
|
@@ -871,8 +871,9 @@ int win_fdccol_count(win_T *wp)
|
||||
}
|
||||
}
|
||||
|
||||
void ui_ext_win_position(win_T *wp)
|
||||
void ui_ext_win_position(win_T *wp, bool validate)
|
||||
{
|
||||
wp->w_pos_changed = false;
|
||||
if (!wp->w_floating) {
|
||||
ui_call_win_pos(wp->w_grid_alloc.handle, wp->handle, wp->w_winrow,
|
||||
wp->w_wincol, wp->w_width, wp->w_height);
|
||||
@@ -910,6 +911,11 @@ void ui_ext_win_position(win_T *wp)
|
||||
grid->handle, row, col, c.focusable,
|
||||
wp->w_grid_alloc.zindex);
|
||||
} else {
|
||||
bool valid = (wp->w_redr_type == 0);
|
||||
if (!valid && !validate) {
|
||||
wp->w_pos_changed = true;
|
||||
return;
|
||||
}
|
||||
// TODO(bfredl): ideally, compositor should work like any multigrid UI
|
||||
// and use standard win_pos events.
|
||||
bool east = c.anchor & kFloatAnchorEast;
|
||||
@@ -923,7 +929,6 @@ void ui_ext_win_position(win_T *wp)
|
||||
comp_col = MAX(MIN(comp_col, Columns - wp->w_width_outer), 0);
|
||||
wp->w_winrow = comp_row;
|
||||
wp->w_wincol = comp_col;
|
||||
bool valid = (wp->w_redr_type == 0);
|
||||
ui_comp_put_grid(&wp->w_grid_alloc, comp_row, comp_col,
|
||||
wp->w_height_outer, wp->w_width_outer, valid, false);
|
||||
ui_check_cursor_grid(wp->w_grid_alloc.handle);
|
||||
@@ -2849,12 +2854,12 @@ int win_close(win_T *win, bool free_buf, bool force)
|
||||
check_cursor();
|
||||
}
|
||||
|
||||
// If last window has a status line now and we don't want one,
|
||||
// remove the status line. Do this before win_equal(), because
|
||||
// it may change the height of a window.
|
||||
last_status(false);
|
||||
|
||||
if (!was_floating) {
|
||||
// If last window has a status line now and we don't want one,
|
||||
// remove the status line. Do this before win_equal(), because
|
||||
// it may change the height of a window.
|
||||
last_status(false);
|
||||
|
||||
if (!curwin->w_floating && p_ea && (*p_ead == 'b' || *p_ead == dir)) {
|
||||
// If the frame of the closed window contains the new current window,
|
||||
// only resize that frame. Otherwise resize all windows.
|
||||
@@ -2898,7 +2903,10 @@ int win_close(win_T *win, bool free_buf, bool force)
|
||||
}
|
||||
|
||||
curwin->w_pos_changed = true;
|
||||
redraw_all_later(UPD_NOT_VALID);
|
||||
if (!was_floating) {
|
||||
// TODO(bfredl): how about no?
|
||||
redraw_all_later(UPD_NOT_VALID);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -5413,7 +5421,7 @@ void win_setheight_win(int height, win_T *win)
|
||||
if (win->w_floating) {
|
||||
win->w_float_config.height = height;
|
||||
win_config_float(win, win->w_float_config);
|
||||
redraw_later(win, UPD_NOT_VALID);
|
||||
redraw_later(win, UPD_VALID);
|
||||
} else {
|
||||
frame_setheight(win->w_frame, height + win->w_hsep_height + win->w_status_height);
|
||||
|
||||
@@ -6059,6 +6067,9 @@ void win_new_height(win_T *wp, int height)
|
||||
wp->w_height = height;
|
||||
wp->w_pos_changed = true;
|
||||
win_set_inner_size(wp, true);
|
||||
if (wp->w_status_height) {
|
||||
wp->w_redr_status = true;
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_to_fraction(win_T *wp, int prev_height)
|
||||
@@ -6196,7 +6207,7 @@ void win_set_inner_size(win_T *wp, bool valid_cursor)
|
||||
if (!exiting && valid_cursor) {
|
||||
scroll_to_fraction(wp, prev_height);
|
||||
}
|
||||
redraw_later(wp, UPD_NOT_VALID); // UPD_SOME_VALID??
|
||||
redraw_later(wp, UPD_SOME_VALID);
|
||||
}
|
||||
|
||||
if (width != wp->w_width_inner) {
|
||||
@@ -6608,7 +6619,6 @@ static void last_status_rec(frame_T *fr, bool statusline, bool is_stl_global)
|
||||
wp->w_hsep_height = 0;
|
||||
comp_col();
|
||||
}
|
||||
redraw_all_later(UPD_SOME_VALID);
|
||||
} else {
|
||||
// For a column or row frame, recursively call this function for all child frames
|
||||
FOR_ALL_FRAMES(fp, fr->fr_child) {
|
||||
@@ -7336,16 +7346,16 @@ void get_framelayout(const frame_T *fr, list_T *l, bool outer)
|
||||
}
|
||||
}
|
||||
|
||||
void win_ui_flush(void)
|
||||
void win_ui_flush(bool validate)
|
||||
{
|
||||
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
||||
if (wp->w_pos_changed && wp->w_grid_alloc.chars != NULL) {
|
||||
if (tp == curtab) {
|
||||
ui_ext_win_position(wp);
|
||||
ui_ext_win_position(wp, validate);
|
||||
} else {
|
||||
ui_call_win_hide(wp->w_grid_alloc.handle);
|
||||
wp->w_pos_changed = false;
|
||||
}
|
||||
wp->w_pos_changed = false;
|
||||
}
|
||||
if (tp == curtab) {
|
||||
ui_ext_win_viewport(wp);
|
||||
|
Reference in New Issue
Block a user