diff options
author | bfredl <bjorn.linse@gmail.com> | 2022-09-22 11:09:33 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-22 11:09:33 +0200 |
commit | 7fc5f6605fb3de361c970a1d22a42a905a072a0c (patch) | |
tree | ffe2148ab3193f2c122ed43e9655e3179b17c1e5 /src/nvim/drawscreen.c | |
parent | 8d13b08a03c31cdb269b7d09c166e0b447f2a303 (diff) | |
parent | 02f8ca59a80cd3570593c717ff6ceadc33239b89 (diff) | |
download | rneovim-7fc5f6605fb3de361c970a1d22a42a905a072a0c.tar.gz rneovim-7fc5f6605fb3de361c970a1d22a42a905a072a0c.tar.bz2 rneovim-7fc5f6605fb3de361c970a1d22a42a905a072a0c.zip |
Merge pull request #20249 from bfredl/cmdmessage
fix(redraw): avoid unnecessary redraws and glitches with floats+messages
Diffstat (limited to 'src/nvim/drawscreen.c')
-rw-r--r-- | src/nvim/drawscreen.c | 68 |
1 files changed, 56 insertions, 12 deletions
diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 957e8ae4da..c95f3f3550 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -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. @@ -998,6 +1018,9 @@ win_update_start: bool scrolled_down = false; // true when scrolled down when w_topline got smaller a bit bool top_to_mod = false; // redraw above mod_top + int bot_scroll_start = 999; // first line that needs to be redrawn due to + // scrolling. only used for EOB + int row; // current window row to display linenr_T lnum; // current buffer lnum to display int idx; // current index in w_lines[] @@ -1022,7 +1045,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; } @@ -1173,6 +1198,7 @@ win_update_start: mod_bot = MAXLNUM; } } + wp->w_redraw_top = 0; // reset for next time wp->w_redraw_bot = 0; @@ -1243,6 +1269,7 @@ win_update_start: // If not the last window, delete the lines at the bottom. // win_ins_lines may fail when the terminal can't do it. win_scroll_lines(wp, 0, i); + bot_scroll_start = 0; if (wp->w_lines_valid != 0) { // Need to update rows that are new, stop at the // first one that scrolled down. @@ -1303,6 +1330,7 @@ win_update_start: if (row > 0) { win_scroll_lines(wp, 0, -row); bot_start = wp->w_grid.rows - row; + bot_scroll_start = bot_start; } if ((row == 0 || bot_start < 999) && wp->w_lines_valid != 0) { // Skip the lines (below the deleted lines) that are still @@ -1680,6 +1708,7 @@ win_update_start: // need to redraw until the end of the window. // Inserting/deleting lines has no use. bot_start = 0; + bot_scroll_start = 0; } else { // Able to count old number of rows: Count new window // rows, and may insert/delete lines @@ -1710,6 +1739,7 @@ win_update_start: } else { win_scroll_lines(wp, row, xtra_rows); bot_start = wp->w_grid.rows + xtra_rows; + bot_scroll_start = bot_start; } } else if (xtra_rows > 0) { // May scroll text down. If there is not enough @@ -1719,6 +1749,7 @@ win_update_start: mod_bot = MAXLNUM; } else { win_scroll_lines(wp, row + old_rows, xtra_rows); + bot_scroll_start = 0; if (top_end > row + old_rows) { // Scrolled the part at the top that requires // updating down. @@ -1908,6 +1939,7 @@ win_update_start: wp->w_botline = lnum; } else { win_draw_end(wp, '@', ' ', true, srow, wp->w_grid.rows, HLF_AT); + set_empty_rows(wp, srow); wp->w_botline = lnum; } } else { @@ -1928,8 +1960,18 @@ win_update_start: // Make sure the rest of the screen is blank. // write the "eob" character from 'fillchars' to rows that aren't part // of the file. - win_draw_end(wp, wp->w_p_fcs_chars.eob, ' ', false, row, wp->w_grid.rows, + // TODO(bfredl): just keep track of the valid EOB area from last redraw? + int lastline = bot_scroll_start; + if (mid_end >= row) { + lastline = MIN(lastline, mid_start); + } + if (mod_bot > buf->b_ml.ml_line_count + 1) { + lastline = 0; + } + + win_draw_end(wp, wp->w_p_fcs_chars.eob, ' ', false, MAX(lastline, row), wp->w_grid.rows, HLF_EOB); + set_empty_rows(wp, row); } kvi_destroy(line_providers); @@ -2041,12 +2083,14 @@ void redraw_buf_later(buf_T *buf, int type) } } -void redraw_buf_line_later(buf_T *buf, linenr_T line) +void redraw_buf_line_later(buf_T *buf, linenr_T line, bool force) { FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - if (wp->w_buffer == buf - && line >= wp->w_topline && line < wp->w_botline) { - redrawWinline(wp, line); + if (wp->w_buffer == buf) { + redrawWinline(wp, MIN(line, buf->b_ml.ml_line_count)); + if (force && line > buf->b_ml.ml_line_count) { + wp->w_redraw_bot = line; + } } } } |