Subject: Re: bug#76186: 31.0.50; (recenter 0) sometimes does not recenter as expected

From: Eli Zaretskii <[email-masked]>
Date: Sun, 02 Mar 2025 10:42:15 +0200

> From: Stephen Berman <[email-masked]>
> Cc: [email-masked],  [email-masked]
> Date: Tue, 25 Feb 2025 16:48:55 +0100
> 
> >> 20570	  else if (CHARPOS (startp) >= BEGV
> >
> > This indicates that one of the conditions below
> >
> >   else if (CHARPOS (startp) >= BEGV
> > 	   && CHARPOS (startp) <= ZV
> > 	   && PT >= CHARPOS (startp)
> > 	   && (CHARPOS (startp) < ZV
> > 	       /* Avoid starting at end of buffer.  */
> > 	       || CHARPOS (startp) == BEGV
> > 	       || !window_outdated (w)))
> >
> > yields false, but which one?
> 
> (gdb) p CHARPOS (startp) >= BEGV
> $24 = 1
> (gdb) p CHARPOS (startp) <= ZV
> $25 = 1
> (gdb) p PT >= CHARPOS (startp)
> $26 = 1
> (gdb) p CHARPOS (startp) < ZV
> $27 = 0
> (gdb) p CHARPOS (startp) == BEGV
> $28 = 0
> (gdb) p !window_outdated (w)
> $29 = 0

So window_outdated returned non-zero.  That function is just

  bool
  window_outdated (struct window *w)
  {
    struct buffer *b = XBUFFER (w->contents);
    return (w->last_modified < BUF_MODIFF (b)
	    || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b));
  }

which means the window's last_modified flag was not updated by the
previous redisplay cycle for some reason.  That probably happens
because some code called mark_window_display_accurate with last
argument 'false', or maybe because that function was not called at the
end of the previous (1st) redisplay cycle in this scenario (recall
that redisplay_window is called twice in this scenario, and it's the
second call that recenters).  If you can find out which call was that,
maybe it will tell us something useful, but in general, if the
window's display is outdated, the display engine will indeed recenter,
because that means the information in window-start is unreliable.  So
I'm guessing that something in the convoluted reproduction recipe
causes Emacs to decide that the window was not fully redrawn, or that
something happened after the 1st redisplay which made the window
outdated, and that is why it centers point in the window.

> Does the trace answer your questions?  If so, can you connect the dots
> for me, because I still don't see why the recentering happens.

Recentering of point in the window is the default strategy of
redisplaying a window when all else failed or was found inapplicable.
That's what happens here, for some subtle reason whose cause is in the
recipe.  AFAIU, point is still at EOB when this happens, so the only
problem is the expectation that window-start will always be at EOB
after the call (recenter 0), which evidently is not 100% reliable.

Thanks.