Subject: bug#61667: 29.0.60; Failure to redisplay

From: Po Lu <[email-masked]>
Date: Wed, 22 Feb 2023 10:41:20 +0800

Eli Zaretskii <[email-masked]> writes:

>> Date: Tue, 21 Feb 2023 19:25:28 +0200
>> Cc: [email-masked], [email-masked]
>> From: Dmitry Gutov <[email-masked]>
>> 
>> > I'm not surer I follow: why should a frame resize in this case?  You
>> > just visit a file in an existing window of an existing frame, right?
>> > Or is the situation more complicated?  If the latter, please tell the
>> > details, they could be relevant.
>> 
>> Given how slow the unoptimized build is, I can usually start (and 
>> finish) typing the command before Emacs has fully finished processing 
>> the init script, including the default face customizations (which result 
>> in frame resizing).
>> 
>> >> So if I wait for it, and then use 'C-x b' (with Ido's support for
>> >> recentf), then I also can trigger the problem.
>> > 
>> > Not following again: wait for what?  And what happens when you use
>> > "C-x b"?
>> 
>> 'C-x b' followed by the file name from history, followed by RET -> 
>> visiting the previously visited file. From recentf.
>> 
>> This behavior is driven by the option ido-virtual-buffers. Unlikely 
>> affects something.
>> 
>> But it allows me to shorten the scenario of visiting a file for the 
>> first time after launching Emacs, so that I can trigger the bug faster 
>> (over several tries).
>
> So you:
>
>   . start Emacs
>   . wait for the initial frame to be redrawn after the init files are
>     processed
>   . visit a file by typing "C-x b" and selecting a file from a list
>
> And then you see an empty window with the frame's title showing the
> file you selected.  Is that correct?  If so, what do you see on the
> mode line as the buffer name?
>
>> Overall, though, the unoptimized build makes it harder to reproduce: 
>> I've only managed that 3 times, so far.
>
> Which likely means this is some kind of timing issue.  Which perhaps
> also explains why trace-redisplay stops it from happening: it slows
> down redisplay because it needs to output the traces.  So we are
> looking at some X or GTK event that comes in and somehow interrupts or
> prevents redisplay from doing its job, after it evidently started
> (because the frame title is updated at the beginning of a redisplay
> cycle)?  Or maybe it's something that prevents us from swapping the
> double-buffering buffers so that the redrawn stuff is actually shown
> on the glass?
>
>> But the echo area is not getting redrawn either: the selection of 
>> buffers to switch to is still visible as it was when I pressed RET. Just 
>> the title bar changes. The echo area is updated together with the main 
>> window showing the buffer.
>
> The echo area is shown in a window, so that seems to be part of not
> updating the windows on display.

Thanks.

Would you please start by instrumenting xterm.c as follows?

diff --git a/src/xterm.c b/src/xterm.c
index 5feaa4aef0f..999ae5d37fb 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -7518,6 +7518,10 @@ XTframe_up_to_date (struct frame *f)
   FRAME_MOUSE_UPDATE (f);
 
 #ifdef HAVE_XDBE
+  fprintf (stderr, "XTframe_up_to_date: %d, %d\n",
+	   buffer_flipping_blocked_p (),
+	   FRAME_X_NEED_BUFFER_FLIP (f));
+
   if (!buffer_flipping_blocked_p ()
       && FRAME_X_NEED_BUFFER_FLIP (f))
     show_back_buffer (f);
@@ -17736,6 +17740,8 @@ x_flush_dirty_back_buffer_on (struct frame *f)
       || !FRAME_X_NEED_BUFFER_FLIP (f))
     return;
 
+  fprintf (stderr, "x_flush_dirty_back_buffer_on: called\n");
+
   show_back_buffer (f);
 #endif
 }

Then, please tell if anything at all is printed when the buffer flipping
fails to happen.

In addition, does this happen on a build without Cairo?  One theory is
that an event somehow arrives during redisplay and causes
`x_flush_dirty_back_buffer_on' to be called, and the Cairo code is
missing a call to `x_mark_frame_dirty' somewhere, which causes the next
buffer flip to not take effect.