Subject: Re: Diff file (Was: Re: bug#49959: 28.0.50; Emacs got quasi freeze)

From: martin rudalics <[email-masked]>
Date: Tue, 31 Aug 2021 18:51:35 +0200

> The problem maybe be fixed, I feel.
 >
 > Sorry, I don't know the confirming method.
 > But, I've never got the rendering issue since applying your patch.
 >
 > Is this fine?

Hopefully.  It doesn't break the behavior under xfce/xfwm4.  I yet have
to test with Gnome and Plasma.  Meanwhile please do the following:

Apply the attached patch which adds a few diagnostics.  Then evaluate

   (setq frame-size-history '(100))

switch to the other virtual desktop, switch back to the Emacs
desktop, evaluate

   (frame--size-history frame)
   (pop-to-buffer "*frame-size-history*")

and tell me what *frame-size-history* contains now.

Then please do the same with Emacs _not_ focused before switching to the
other desktop.

And please also try the following: With emacs -Q put into *scratch*
the lines

(setq frame (make-frame))
(frame-visible-p frame)
(make-frame-invisible frame)
(make-frame-visible frame)
(iconify-frame frame)

Now use C-x C-e after any of these forms to first make FRAME and, for
example, make FRAME invisible, then make it iconified, then make it
visible and so on.  After every step use the `frame-visible-p' form to
check what Emacs thinks FRAME is.  If you find a transition that you
think is not correct, please tell me.

Thanks again, martin
diff --git a/src/w32term.c b/src/w32term.c
index 8eb90669d5..9663628045 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -6889,11 +6889,6 @@ w32_make_frame_invisible (struct frame *f)

   my_show_window (f, FRAME_W32_WINDOW (f), SW_HIDE);

-  /* We can't distinguish this from iconification
-     just by the event that we get from the server.
-     So we can't win using the usual strategy of letting
-     FRAME_SAMPLE_VISIBILITY set this.  So do it by hand,
-     and synchronize with the server to make sure we agree.  */
   SET_FRAME_VISIBLE (f, 0);
   SET_FRAME_ICONIFIED (f, false);

diff --git a/src/xdisp.c b/src/xdisp.c
index 049d5ed7b5..b6baf4fd27 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -15429,9 +15429,6 @@ redisplay_internal (void)
       FRAME_TTY (sf)->previous_frame = sf;
     }

-  /* Set the visible flags for all frames.  Do this before checking for
-     resized or garbaged frames; they want to know if their frames are
-     visible.  See the comment in frame.h for FRAME_SAMPLE_VISIBILITY.  */
   number_of_visible_frames = 0;

   FOR_EACH_FRAME (tail, frame)
diff --git a/src/xterm.c b/src/xterm.c
index 6c6a62adb2..d5e40ffcc8 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -8243,12 +8243,32 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       f = x_window_to_frame (dpyinfo, event->xexpose.window);
       if (f)
         {
+	  if (CONSP (frame_size_history))
+	    {
+	      if (FRAME_VISIBLE_P (f))
+		frame_size_history_plain
+		  (f, build_string ("Expose, visible"));
+	      else
+		frame_size_history_plain
+		  (f, build_string ("Expose, not visible"));
+	    }
+
           if (!FRAME_VISIBLE_P (f))
             {
               block_input ();
 	      /* The following two are commented out to avoid that a
 		 plain invisible frame gets reported as iconified.  That
-		 problem occurred first for Emacs 26 and is described in
+		 problem occurred first for Emacs 26 with GTK3 and is
+		 the result of the following actions:
+
+		 (1) x_make_frame_invisible sets f->visible to 0.
+
+		 (2) We get an (unexpected) Expose event for f and here
+		     set f->visible to 1.
+
+		 (3) The subsequent UnmapNotify event finds f->visible
+		     is 1 and sets f->iconified true.
+
 		 https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.  */
 /** 	      SET_FRAME_VISIBLE (f, 1); **/
 /** 	      SET_FRAME_ICONIFIED (f, false); **/
@@ -8839,26 +8859,24 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       goto OTHER;

     case FocusIn:
-#ifndef USE_GTK
       /* Some WMs (e.g. Mutter in Gnome Shell), don't unmap
          minimized/iconified windows; thus, for those WMs we won't get
          a MapNotify when unminimizing/deconifying.  Check here if we
-         are deiconizing a window (Bug42655).
-
-	 But don't do that on GTK since it may cause a plain invisible
-	 frame get reported as iconified, compare
-	 https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.
-	 That is fixed above but bites us here again.  */
+         are deiconifying a window (Bug42655).  */
       f = any;
+      /* Should we handle invisible frames here too?  */
       if (f && FRAME_ICONIFIED_P (f))
 	{
+	  if (CONSP (frame_size_history))
+	    frame_size_history_plain
+	      (f, build_string ("FocusIn, was iconified"));
+
           SET_FRAME_VISIBLE (f, 1);
           SET_FRAME_ICONIFIED (f, false);
           f->output_data.x->has_been_visible = true;
           inev.ie.kind = DEICONIFY_EVENT;
           XSETFRAME (inev.ie.frame_or_window, f);
         }
-#endif /* USE_GTK */

       x_detect_focus_change (dpyinfo, any, event, &inev.ie);
       goto OTHER;
@@ -11936,11 +11954,6 @@ x_make_frame_invisible (struct frame *f)

   x_sync (f);

-  /* We can't distinguish this from iconification
-     just by the event that we get from the server.
-     So we can't win using the usual strategy of letting
-     FRAME_SAMPLE_VISIBILITY set this.  So do it by hand,
-     and synchronize with the server to make sure we agree.  */
   SET_FRAME_VISIBLE (f, 0);
   SET_FRAME_ICONIFIED (f, false);