Subject: bug#10304: 24.0.92: display bug

From: Eli Zaretskii <[email-masked]>
Date: Sat, 17 Jan 2015 13:34:17 +0200

> From: Lars Magne Ingebrigtsen <[email-masked]>
> Cc: [email-masked]
> Date: Fri, 16 Jan 2015 00:50:53 +0100
> 
> Eli Zaretskii <[email-masked]> writes:
> 
> > I'd like to prepare an additional patch which will allow you to
> > collect more data that might reveal why Emacs behaves like that.  In
> > order to test the patch, is it possible for you to give me
> > instructions for how to display that article, starting from "emacs -Q"?
> 
> That was easier than I had thought.  I had forgotten about this entry
> point to Gnus.
> 
> `eval'-ing this from "emacs -Q" should work:
> 
> (gnus-fetch-group "nntp+news.gmane.org:gwene.com.wordpress.arnoldzwicky" '(3401))
> 
> although you will be queried about the self-signed certificate.

Thanks, that was easy enough.  Granted, I don't see any redisplay
problems with that article, like you do.

Below please find a new patch to add trace data.  This is _instead_ of
the previous patch, not in addition to it, and it's relative to the
current master (I hope the problem is still visible with the current
master).

After applying the patch, please again do whatever is needed to
reproduce the problem, and please tell me which part(s) of the trace
are emitted when the display becomes corrupted.

Before invoking "M-x trace-redisplay", please disable
blink-cursor-mode (as it triggers too many unnecessary redisplay
cycles that muddy the water), and also delete ("C-x 0") the summary
window, so that redisplay has less windows to refresh (which will
again make the signal to noise ratio of the trace better).

Thanks.

Here's the patch:

diff --git a/src/dispnew.c b/src/dispnew.c
index a643d58..c41584d 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -3606,6 +3606,8 @@ struct glyph_row *
 			   TEXT_AREA, desired_row->used[TEXT_AREA]);
 
       /* Clear to end of window.  */
+      TRACE ((stderr, "clear_end_of_line1(%d..): vpos = %d  Y = %d\n",
+	      desired_row->used[TEXT_AREA], vpos, desired_row->y));
       rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1);
       changed_p = 1;
 
@@ -3642,6 +3644,8 @@ struct glyph_row *
       i = 0;
       x = desired_row->x;
 
+      TRACE ((stderr, "detect common glyphs for row at vpos = %d\n", vpos));
+
       /* Loop over glyphs that current and desired row may have
 	 in common.  */
       while (i < stop)
@@ -3743,6 +3747,8 @@ struct glyph_row *
 		}
 
 	      output_cursor_to (w, vpos, start_hpos, desired_row->y, start_x);
+	      TRACE ((stderr, "write different glyphs %d..%d at vpos = %d\n",
+		      start_hpos, i, vpos));
 	      rif->write_glyphs (w, updated_row, start,
 				 TEXT_AREA, i - start_hpos);
 	      changed_p = 1;
@@ -3753,6 +3759,8 @@ struct glyph_row *
       if (i < desired_row->used[TEXT_AREA])
 	{
 	  output_cursor_to (w, vpos, i, desired_row->y, x);
+	  TRACE ((stderr, "write the rest %d..%d at vpos = %d\n",
+		  i, desired_row->used[TEXT_AREA], vpos));
 	  rif->write_glyphs (w, updated_row, desired_glyph,
 			     TEXT_AREA, desired_row->used[TEXT_AREA] - i);
 	  changed_p = 1;
@@ -3769,6 +3777,7 @@ struct glyph_row *
 		   || ((desired_row->used[TEXT_AREA]
 			== current_row->used[TEXT_AREA])
 		       && MATRIX_ROW_EXTENDS_FACE_P (current_row)));
+	  TRACE ((stderr, "nothing to clear at vpos = %d\n", vpos));
 	}
       else if (MATRIX_ROW_EXTENDS_FACE_P (current_row))
 	{
@@ -3776,6 +3785,8 @@ struct glyph_row *
 	  if (i >= desired_row->used[TEXT_AREA])
 	    output_cursor_to (w, vpos, i, desired_row->y,
 			      desired_row->pixel_width);
+	  TRACE ((stderr, "clear_end_of_line2(%d..): vpos = %d  Y = %d\n",
+		  i, vpos, desired_row->y));
 	  rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1);
 	  changed_p = 1;
 	}
@@ -3804,6 +3815,8 @@ struct glyph_row *
 	    }
 	  else
 	    xlim = current_row->pixel_width;
+	  TRACE ((stderr, "clear_end_of_line3(%d..): vpos = %d  Y = %d\n",
+		  i, vpos, desired_row->y));
 	  rif->clear_end_of_line (w, updated_row, TEXT_AREA, xlim);
 	  changed_p = 1;
 	}
diff --git a/src/xdisp.c b/src/xdisp.c
index f006f8e..b70ee7a 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -27178,6 +27178,9 @@ and buffer to use as the context for the formatting (defaults
   from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, w->output_cursor.y));
   to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
 
+  TRACE ((stderr, "clear_frame_area: [%d - %d] [%d - %d]\n",
+	  from_x, to_x, from_y, to_y));
+
   /* Prevent inadvertently clearing to end of the X window.  */
   if (to_x > from_x && to_y > from_y)
     {