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

From: Eli Zaretskii <[email-masked]>
Date: Sat, 22 Feb 2025 15:32:28 +0200

> From: Stephen Berman <[email-masked]>
> Cc: [email-masked],  [email-masked]
> Date: Sat, 22 Feb 2025 14:08:07 +0100
> 
> > If you can investigate the situation where it happens and describe
> > what goes on there, or maybe even suggest what to do about that, it
> > will be very appreciated.  Failing that, I hope that you could at
> > least answer the questions I posted about what is special in the
> > situation where it does happen.  If you can show a simple recipe that
> > demonstrates the issue without looping endlessly, it will also help.
> 
> In the attached file, I've refactored the second code snippet Markus
> posted into a single command, which facilitated experimenting with it.
> The following is a summary of my observations from experimenting with
> the code.  I don't know how useful such impressions are, but that's the
> best I could come up with (I tried using Edebug but it alters the
> display configuration so I could not get the same test results).
> 
> First, I found that I can reproduce the unexpected recentering without
> disabling the menu bar, tool bar and scroll bar, and using the default
> frame height and width as well as the default font specification.
> Moreover, AFAICT the dimensions and placement of the child frame, and
> whether the buffer displayed in the child frame has text, are
> irrelevant.  (In the attached file the corresponding lines of code are
> all commented out.)  However, I cannot reproduce the unexpected
> recentering without having a child frame nor without either a loop or
> manual iteration -- but sometimes only a single iteration suffices (more
> on that below).
> 
> When I start Emacs like this:
> 
> emacs -Q -l bug#76186.el
> 
> and, if the mouse pointer is over the Emacs frame, do not touch the
> mouse, then after 501 iterations the loop stops (I've also done tests
> with more than 10000 iterations with the same results) and the message
> "window-start=793, point-max=793 in run 501" is displayed, indicating
> the expected result of `(recenter 0)'.  However, in the displayed
> "sample" buffer, point-max is vertically centered in the window (as
> after `(recenter)') and window-start is 671.
> 
> If I restart Emacs as above and while the loop is running continuously
> move the mouse over the frame, I see multiple messages
> "window-start=671, point-max=793 in run <N>", indicating the unexpected
> recentering, and then a new series of test runs commences.  I
> implemented a condition to stop looping when the unexpected recentering
> happens on the first iteration (i.e., when N=1), and in all my tests
> when moving the mouse over the frame this condition is satisfied at some
> point.  The display of the buffer is as above (i.e., as expected when
> window-start differs from point-max).  (I tried to programmatically
> emulate moving the mouse over the frame with the help of
> `set-mouse-position' and `set-mouse-pixel-position', but in both cases
> the results were as in the first test without moving the mouse over the
> frame.  I noticed that when I manually move the mouse over the frame,
> the pointer has the shape of an arrow, while with
> set-mouse-{pixel-}position the pointer is an "I-beam".)
> 
> If I uncomment the third invocation of `redisplay' in the attached file
> and restart Emacs as above and do not move the mouse over the frame, the
> result, and the display, on stopping after 501 iterations is as
> described above.  However, if I then type `M-x sometimes-not-recentering
> RET' and again do not move the mouse over the frame, then on stopping
> after 501 iterations the same message "window-start=793, point-max=793
> in run 501" is shown but now the buffer display fits the message: point
> is at the top left of the window.  Repeating `M-x
> sometimes-not-recentering RET' gives the same result and display, though
> sometimes there is also a series of test runs (< 501) showing
> window-point and point-max differing, but then the next (automatically
> started) series ends after 501 iterations with these again identical and
> point displayed at top left in the window.  However, this test
> configuration appears to be unstable: sometimes on starting Emacs as
> above I have gotten the result I get when moving the mouse over the
> frame, but this appears to be rare and unpredictable.
> 
> If I again comment out the third invocation of `redisplay' and also
> comment out the first invocation (thus only the second invocation is
> executed), then on starting Emacs as above, in all tests I've made with
> this configuration the loop stops immediately after one iteration (one
> test series) with the message "window-start=671, point-max=793 in run 1"
> and the same display as after the loop stops when moving the mouse over
> the frame.  If I then type `M-x sometimes-not-recentering RET', the
> result and display are the same, sometimes immediately after one
> iteration, sometimes after several series of test runs.
> 
> If I leave the first and third invocations of `redisplay' commented out
> and also comment out the invocation of `sometimes-not-recentering' at
> the bottom of the file, and then start Emacs as above and type `M-x
> sometimes-not-recentering RET', then the results and display are
> invariably with window-point and point-max differing, but, unlike on all
> my tests when the command is executed on loading the file, this
> sometimes but not always happens after one test series of one iteration.

Thanks.  I'm afraid I'm none the wiser, because I see none of the
phenomena you describe on my system.  Whatever I do, the test always
runs to completion, and the last screen shows point at EOB.

Some parts of what you describe seem to indicate that the problem is
not with 'recenter' itself, but with the following redisplay cycle,
which, for some reason, considers the window-start position
inappropriate and recenters point on display.  But I have no idea why,
and it is impossible to debug this when the problem happens as part of
500 iterations.