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 */