fix(column): unnecessary redraws with resized 'statuscolumn' (#32944)

Problem:  Since 3cb1e825, all windows with 'statuscolumn' set, and a
          resized 'signcolumn' for a particular buffer are marked
          to be fully redrawn when the first window is encountered.
          The "resized" variable is only unset after all windows have
          been drawn, so this results in windows that have just been
          draw to be marked for redraw again, even though the
          signcolumn did not change size again.
Solution: Replace the `resized` variable with a `last_max` variable that
          is changed when the first window into buf is encountered.
This commit is contained in:
luukvbaal
2025-03-17 21:52:45 +01:00
committed by GitHub
parent 5440e59247
commit 063b69bab4
3 changed files with 7 additions and 10 deletions

View File

@ -702,8 +702,8 @@ struct file_buffer {
struct {
int max; // maximum number of signs on a single line
int last_max; // value of max when the buffer was last drawn
int count[SIGN_SHOW_MAX]; // number of lines with number of signs
bool resized; // whether max changed at start of redraw
bool autom; // whether 'signcolumn' is displayed in "auto:n>1"
// configured window. "b_signcols" calculation
// is skipped if false.

View File

@ -245,8 +245,8 @@ void buf_remove_decor_sh(buf_T *buf, int row1, int row2, DecorSignHighlight *sh)
buf_signcols_count_range(buf, row1, row2, -1, kFalse);
} else {
may_force_numberwidth_recompute(buf, true);
buf->b_signcols.resized = true;
buf->b_signcols.max = buf->b_signcols.count[0] = 0;
buf->b_signcols.count[0] = 0;
buf->b_signcols.max = 0;
}
}
}
@ -1069,7 +1069,6 @@ void buf_signcols_count_range(buf_T *buf, int row1, int row2, int add, TriState
if (clear != kTrue && width > 0) {
buf->b_signcols.count[width - 1]++;
if (width > buf->b_signcols.max) {
buf->b_signcols.resized = true;
buf->b_signcols.max = width;
}
}

View File

@ -671,11 +671,10 @@ int update_screen(void)
win_check_ns_hl(NULL);
// Reset b_mod_set and b_signcols.resized flags. Going through all windows is
// probably faster than going through all buffers (there could be many buffers).
// Reset b_mod_set. Going through all windows is probably faster than going
// through all buffers (there could be many buffers).
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
wp->w_buffer->b_mod_set = false;
wp->w_buffer->b_signcols.resized = false;
}
updating_screen = false;
@ -1242,12 +1241,11 @@ static bool win_redraw_signcols(win_T *wp)
}
while (buf->b_signcols.max > 0 && buf->b_signcols.count[buf->b_signcols.max - 1] == 0) {
buf->b_signcols.resized = true;
buf->b_signcols.max--;
}
int width = MIN(wp->w_maxscwidth, buf->b_signcols.max);
bool rebuild_stc = buf->b_signcols.resized && *wp->w_p_stc != NUL;
bool rebuild_stc = buf->b_signcols.max != buf->b_signcols.last_max && *wp->w_p_stc != NUL;
if (rebuild_stc) {
wp->w_nrwidth_line_count = 0;
@ -1536,11 +1534,11 @@ static void win_update(win_T *wp)
FOR_ALL_WINDOWS_IN_TAB(win, curtab) {
if (win->w_buffer == wp->w_buffer && win_redraw_signcols(win)) {
win->w_lines_valid = 0;
changed_line_abv_curs_win(win);
redraw_later(win, UPD_NOT_VALID);
}
}
buf->b_signcols.last_max = buf->b_signcols.max;
init_search_hl(wp, &screen_search_hl);