Mercurial > vim
diff src/screen.c @ 12152:69af108df70e v8.0.0956
patch 8.0.0956: scrolling in a terminal window has flicker
commit https://github.com/vim/vim/commit/cfce71710b6a2e1fb7f7f27d2a359e4b926f3af9
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Aug 17 20:31:48 2017 +0200
patch 8.0.0956: scrolling in a terminal window has flicker
Problem: Scrolling in a terminal hwindow as flicker when the Normal
background differs from the terminal window background.
Solution: Set the attribute to clear with.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 17 Aug 2017 20:45:04 +0200 |
parents | 68c593f649d1 |
children | d0b039e2ed56 |
line wrap: on
line diff
--- a/src/screen.c +++ b/src/screen.c @@ -151,13 +151,13 @@ static void screen_char(unsigned off, in static void screen_char_2(unsigned off, int row, int col); #endif static void screenclear2(void); -static void lineclear(unsigned off, int width); +static void lineclear(unsigned off, int width, int attr); static void lineinvalid(unsigned off, int width); #ifdef FEAT_WINDOWS static void linecopy(int to, int from, win_T *wp); static void redraw_block(int row, int end, win_T *wp); #endif -static int win_do_lines(win_T *wp, int row, int line_count, int mayclear, int del); +static int win_do_lines(win_T *wp, int row, int line_count, int mayclear, int del, int clear_attr); static void win_rest_invalid(win_T *wp); static void msg_pos_mode(void); static void recording_mode(int attr); @@ -609,7 +609,8 @@ update_screen(int type_arg) else if (type != CLEAR) { check_for_delay(FALSE); - if (screen_ins_lines(0, 0, msg_scrolled, (int)Rows, NULL) == FAIL) + if (screen_ins_lines(0, 0, msg_scrolled, (int)Rows, 0, NULL) + == FAIL) type = CLEAR; FOR_ALL_WINDOWS(wp) { @@ -1537,7 +1538,8 @@ win_update(win_T *wp) if (row > 0) { check_for_delay(FALSE); - if (win_del_lines(wp, 0, row, FALSE, wp == firstwin) == OK) + if (win_del_lines(wp, 0, row, FALSE, wp == firstwin, 0) + == OK) bot_start = wp->w_height - row; else mid_start = 0; /* redraw all lines */ @@ -2003,7 +2005,7 @@ win_update(win_T *wp) { check_for_delay(FALSE); if (win_del_lines(wp, row, - -xtra_rows, FALSE, FALSE) == FAIL) + -xtra_rows, FALSE, FALSE, 0) == FAIL) mod_bot = MAXLNUM; else bot_start = wp->w_height + xtra_rows; @@ -6773,7 +6775,7 @@ win_redr_status_matches( * no room, scroll the screen one line up. */ if (cmdline_row == Rows - 1) { - screen_del_lines(0, 0, 1, (int)Rows, TRUE, NULL); + screen_del_lines(0, 0, 1, (int)Rows, TRUE, 0, NULL); ++msg_scrolled; } else @@ -9074,7 +9076,7 @@ screenclear2(void) /* blank out ScreenLines */ for (i = 0; i < Rows; ++i) { - lineclear(LineOffset[i], (int)Columns); + lineclear(LineOffset[i], (int)Columns, 0); LineWraps[i] = FALSE; } @@ -9114,7 +9116,7 @@ screenclear2(void) * Clear one line in ScreenLines. */ static void -lineclear(unsigned off, int width) +lineclear(unsigned off, int width, int attr) { (void)vim_memset(ScreenLines + off, ' ', (size_t)width * sizeof(schar_T)); #ifdef FEAT_MBYTE @@ -9122,7 +9124,7 @@ lineclear(unsigned off, int width) (void)vim_memset(ScreenLinesUC + off, 0, (size_t)width * sizeof(u8char_T)); #endif - (void)vim_memset(ScreenAttrs + off, 0, (size_t)width * sizeof(sattr_T)); + (void)vim_memset(ScreenAttrs + off, attr, (size_t)width * sizeof(sattr_T)); } /* @@ -9508,7 +9510,7 @@ win_ins_lines( if (line_count > wp->w_height - row) line_count = wp->w_height - row; - retval = win_do_lines(wp, row, line_count, mayclear, FALSE); + retval = win_do_lines(wp, row, line_count, mayclear, FALSE, 0); if (retval != MAYBE) return retval; @@ -9523,7 +9525,7 @@ win_ins_lines( if (wp->w_next != NULL || wp->w_status_height) { if (screen_del_lines(0, W_WINROW(wp) + wp->w_height - line_count, - line_count, (int)Rows, FALSE, NULL) == OK) + line_count, (int)Rows, FALSE, 0, NULL) == OK) did_delete = TRUE; else if (wp->w_next) return FAIL; @@ -9547,7 +9549,7 @@ win_ins_lines( ' ', ' ', 0); } - if (screen_ins_lines(0, W_WINROW(wp) + row, line_count, (int)Rows, NULL) + if (screen_ins_lines(0, W_WINROW(wp) + row, line_count, (int)Rows, 0, NULL) == FAIL) { /* deletion will have messed up other windows */ @@ -9577,7 +9579,8 @@ win_del_lines( int row, int line_count, int invalid, - int mayclear) + int mayclear, + int clear_attr) /* for clearing lines */ { int retval; @@ -9587,12 +9590,12 @@ win_del_lines( if (line_count > wp->w_height - row) line_count = wp->w_height - row; - retval = win_do_lines(wp, row, line_count, mayclear, TRUE); + retval = win_do_lines(wp, row, line_count, mayclear, TRUE, clear_attr); if (retval != MAYBE) return retval; if (screen_del_lines(0, W_WINROW(wp) + row, line_count, - (int)Rows, FALSE, NULL) == FAIL) + (int)Rows, FALSE, clear_attr, NULL) == FAIL) return FAIL; #ifdef FEAT_WINDOWS @@ -9603,7 +9606,7 @@ win_del_lines( if (wp->w_next || wp->w_status_height || cmdline_row < Rows - 1) { if (screen_ins_lines(0, W_WINROW(wp) + wp->w_height - line_count, - line_count, (int)Rows, NULL) == FAIL) + line_count, (int)Rows, clear_attr, NULL) == FAIL) { wp->w_redr_status = TRUE; win_rest_invalid(wp->w_next); @@ -9630,7 +9633,8 @@ win_do_lines( int row, int line_count, int mayclear, - int del) + int del, + int clear_attr) { int retval; @@ -9694,10 +9698,10 @@ win_do_lines( scroll_region_set(wp, row); if (del) retval = screen_del_lines(W_WINROW(wp) + row, 0, line_count, - wp->w_height - row, FALSE, wp); + wp->w_height - row, FALSE, clear_attr, wp); else retval = screen_ins_lines(W_WINROW(wp) + row, 0, line_count, - wp->w_height - row, wp); + wp->w_height - row, clear_attr, wp); #ifdef FEAT_WINDOWS if (scroll_region && (wp->w_width == Columns || *T_CSV != NUL)) #endif @@ -9771,6 +9775,7 @@ screen_ins_lines( int row, int line_count, int end, + int clear_attr, win_T *wp) /* NULL or window to use width from */ { int i; @@ -9851,7 +9856,7 @@ screen_ins_lines( */ if (type == USE_T_CD || type == USE_T_CDL || type == USE_T_CE || type == USE_T_DL) - return screen_del_lines(off, row, line_count, end, FALSE, wp); + return screen_del_lines(off, row, line_count, end, FALSE, 0, wp); /* * If text is retained below the screen, first clear or delete as many @@ -9859,7 +9864,7 @@ screen_ins_lines( * the deleted lines won't later surface during a screen_del_lines. */ if (*T_DB) - screen_del_lines(off, end - line_count, line_count, end, FALSE, wp); + screen_del_lines(off, end - line_count, line_count, end, FALSE, 0, wp); #ifdef FEAT_CLIPBOARD /* Remove a modeless selection when inserting lines halfway the screen @@ -9902,7 +9907,8 @@ screen_ins_lines( linecopy(j + line_count, j, wp); j += line_count; if (can_clear((char_u *)" ")) - lineclear(LineOffset[j] + wp->w_wincol, wp->w_width); + lineclear(LineOffset[j] + wp->w_wincol, wp->w_width, + clear_attr); else lineinvalid(LineOffset[j] + wp->w_wincol, wp->w_width); LineWraps[j] = FALSE; @@ -9920,7 +9926,7 @@ screen_ins_lines( LineOffset[j + line_count] = temp; LineWraps[j + line_count] = FALSE; if (can_clear((char_u *)" ")) - lineclear(temp, (int)Columns); + lineclear(temp, (int)Columns, clear_attr); else lineinvalid(temp, (int)Columns); } @@ -9928,6 +9934,8 @@ screen_ins_lines( screen_stop_highlight(); windgoto(cursor_row, 0); + if (clear_attr != 0) + screen_start_highlight(clear_attr); #ifdef FEAT_WINDOWS /* redraw the characters */ @@ -9993,6 +10001,7 @@ screen_del_lines( int line_count, int end, int force, /* even when line_count > p_ttyscroll */ + int clear_attr, /* used for clearing lines */ win_T *wp UNUSED) /* NULL or window to use width from */ { int j; @@ -10136,7 +10145,8 @@ screen_del_lines( linecopy(j - line_count, j, wp); j -= line_count; if (can_clear((char_u *)" ")) - lineclear(LineOffset[j] + wp->w_wincol, wp->w_width); + lineclear(LineOffset[j] + wp->w_wincol, wp->w_width, + clear_attr); else lineinvalid(LineOffset[j] + wp->w_wincol, wp->w_width); LineWraps[j] = FALSE; @@ -10155,13 +10165,16 @@ screen_del_lines( LineOffset[j - line_count] = temp; LineWraps[j - line_count] = FALSE; if (can_clear((char_u *)" ")) - lineclear(temp, (int)Columns); + lineclear(temp, (int)Columns, clear_attr); else lineinvalid(temp, (int)Columns); } } - screen_stop_highlight(); + if (screen_attr != clear_attr) + screen_stop_highlight(); + if (clear_attr != 0) + screen_start_highlight(clear_attr); #ifdef FEAT_WINDOWS /* redraw the characters */