Subject: Re: bug#16736: Compiling a Lisp file causes display to flash off and on

From: Eli Zaretskii <[email-masked]>
Date: Sat, 15 Feb 2014 10:24:44 +0200

> From: Glenn Morris <[email-masked]>
> Cc: [email-masked]
> Date: Fri, 14 Feb 2014 02:48:31 -0500
> 
> Eli Zaretskii wrote:
> 
> > I tried to reproduce your original report, but couldn't, perhaps
> > because I couldn't find a large enough Lisp file that compiles without
> > warnings.  Can you tell which file did you use?
> 
> I think I randomly used progmodes/scheme.el, but added
> 
> (require 'gnus)
> (require 'org)
> 
> at the start, and deleted gnus/*.elc and org/*.elc to slow things down.
> 
> Basically make the slowest compilation you can, so long as there are no
> warnings. It seems to be right at the end of the compilation that the
> flash occurs.

I don't see any flash here.

What you describe, viz.:

> During the resulting compilation, at some point it looks like the Emacs
> display goes completely blank. It happens a bit fast, so it is hard to
> say exactly. It does not look to me as if it is switching to another
> buffer (Compile-Log) and back again. It's like the display flashes off
> and on. The tool-bar, mode line also disappear.

sounds like the frame is cleared and completely redrawn, which I won't
expect during byte-compile, which only redisplays the echo area.  If I
put a breakpoint in clear_frame, it is never hit during your recipe.

> > As for toolbar flickering with repeated "C-x 2" and "C-x 1", I don't
> > see it here.  Is this with a configuration where Emacs draws the
> > toolbar, or is the toolbar drawn by the toolkit?
> 
> --with-x-toolkit=athena --without-toolkit-scroll-bars

These symptoms seem to indicate that the tool bar is redrawn, whereas
it shouldn't be, because its content is unchanged by "C-x 2".  I don't
see any flickering here, so please step with GDB through the affected
code, as described below, and tell what you see.

I also tried this recipe:

  (while t
    (split-window-below)
    (sit-for 0.05)
    (delete-other-windows)
    (sit-for 0.05))

Typing "C-x C-e" at the right paren of this in *scratch*, I see no
flickering in the tool bar.  Do you?

To find out why does the tool-bar flicker, please step into the
portion of redisplay that redraws the tool bar.  Its entry point is in
update_frame, like this:

  #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
	/* Update the tool-bar window, if present.  */
	if (WINDOWP (f->tool_bar_window))
	  {
	    struct window *w = XWINDOW (f->tool_bar_window);

	    /* Update tool-bar window.  */
	    if (w->must_be_updated_p)
	      {
		Lisp_Object tem;

		update_window (w, 1);
		w->must_be_updated_p = false;

		/* Swap tool-bar strings.  We swap because we want to
		   reuse strings.  */
		tem = f->current_tool_bar_string;
		fset_current_tool_bar_string (f, f->desired_tool_bar_string);
		fset_desired_tool_bar_string (f, tem);
	      }
	  }
  #endif

Please step into the update_window call above.  There you should see
that we perform this loop:

      /* Update the rest of the lines.  */
      for (; row < end && (force_p || !input_pending); ++row)
	/* scrolling_window resets the enabled_p flag of the rows it
	   reuses from current_matrix.  */
	if (row->enabled_p)
	  {

Then step into update_window_line call in that loop.  The glyph rows
of the tool-bar window don't have marginal areas, so when the loop
calls update_window_line, only update_text_area is called from
update_window_line.  There's call in update_text_area that compares
the glyph row of the current glyph matrix (which reflects what is on
the screen) and the desired glyph matrix (which says what should be on
the screen).  The comparison code starts with this:

      stop = min (current_row->used[TEXT_AREA], desired_stop_pos);
      i = 0;
      x = desired_row->x;

      /* Loop over glyphs that current and desired row may have
	 in common.  */
      while (i < stop)
	{

In my case, current_row and desired_row are exactly equal, so the tool
bar is never redrawn.  Please see if things are different in your
case, and why.

You can display the contents of the glyph row with the pgrowx command
(defined on src/.gdbinit), like this:

  (gdb) pgrowx current_row
  TEXT: 13 glyphs
    0    0: IMAGE[10] str=0x3a9f394[0] w=35 a+d=14+21 face=3 MB [ slice=0,0,24,24
    1   35: IMAGE[11] str=0x3a9f394[1] w=34 a+d=14+21 face=3 MB slice=0,0,24,24
    2   69: IMAGE[12] str=0x3a9f394[2] w=29 a+d=14+21 face=3 MB slice=0,0,19,24
    3   98: IMAGE[13] str=0x3a9f394[3] w=34 a+d=14+21 face=3 MB slice=0,0,24,24
    4  132: IMAGE[14] str=0x3a9f394[4] w=34 a+d=14+21 face=3 MB slice=0,0,24,24
    5  166: IMAGE[15] str=0x3a9f394[5] w=12 a+d=14+21 face=3 MB slice=0,0,2,24
    6  178: IMAGE[16] str=0x3a9f394[6] w=34 a+d=14+21 face=3 MB slice=0,0,24,24
    7  212: IMAGE[15] str=0x3a9f394[7] w=12 a+d=14+21 face=3 MB slice=0,0,2,24
    8  224: IMAGE[17] str=0x3a9f394[8] w=34 a+d=14+21 face=3 MB slice=0,0,24,24
    9  258: IMAGE[18] str=0x3a9f394[9] w=34 a+d=14+21 face=3 MB slice=0,0,24,24
   10  292: IMAGE[19] str=0x3a9f394[10] w=34 a+d=14+21 face=3 MB slice=0,0,24,24
   11  326: IMAGE[15] str=0x3a9f394[11] w=12 a+d=14+21 face=3 MB slice=0,0,2,24
   12  338: IMAGE[20] str=0x3a9f394[12] w=34 a+d=14+21 face=3 MB ] slice=0,0,24,24

Thanks.