Subject: bug#49959: 28.0.50; Emacs got quasi freeze

From: martin rudalics <[email-masked]>
Date: Tue, 24 Aug 2021 11:41:52 +0200

> That is, when
 >
 > Tue Aug 24 12:37:39 JST 2021
 > _NET_WM_STATE(ATOM) = _NET_WM_STATE_HIDDEN
 >
 > appears, it doesn't start rendering (= enlightenment doesn't remove
 > this property).

So it _is_ a PropertyNotify event we should react to.  I'll attach yet
another patch to that purpose.

martin
diff --git a/src/termhooks.h b/src/termhooks.h
index 1d3cdc8fe8..479b8a1c29 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -168,7 +168,8 @@ #define EMACS_TERMHOOKS_H
 				   Lisp-level event value.
 				   (Only the toolkit version uses these.)  */
   ICONIFY_EVENT,		/* An X client iconified this window.  */
-  DEICONIFY_EVENT,		/* An X client deiconified this window.  */
+  DEICONIFY_EVENT,		/* An X client deiconified this window
+				   or made it visible.  */
   MENU_BAR_ACTIVATE_EVENT,      /* A button press in the menu bar
 				   (toolkit version only).  */
   DRAG_N_DROP_EVENT,		/* A drag-n-drop event is generated when
diff --git a/src/xterm.c b/src/xterm.c
index 6c6a62adb2..82d2ae3a52 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -8166,22 +8166,19 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       f = x_top_window_to_frame (dpyinfo, event->xproperty.window);
       if (f && event->xproperty.atom == dpyinfo->Xatom_net_wm_state)
 	{
+	  bool was_iconified = FRAME_ICONIFIED_P (f);
           bool not_hidden = x_handle_net_wm_state (f, &event->xproperty);

-	  if (not_hidden && FRAME_ICONIFIED_P (f))
+	  if (not_hidden)
 	    {
 	      if (CONSP (frame_size_history))
 		frame_size_history_plain
-		  (f, build_string ("PropertyNotify, not hidden & iconified"));
+		  (f, build_string ("PropertyNotify, not hidden"));

-	      /* Gnome shell does not iconify us when C-z is pressed.
-		 It hides the frame.  So if our state says we aren't
-		 hidden anymore, treat it as deiconified.  */
+	      SET_FRAME_GARBAGED (f);
 	      SET_FRAME_VISIBLE (f, 1);
-	      SET_FRAME_ICONIFIED (f, false);
-
 	      f->output_data.x->has_been_visible = true;
-	      inev.ie.kind = DEICONIFY_EVENT;
+
 #if defined USE_GTK && defined HAVE_GTK3
 	      /* If GTK3 wants to impose some old size here (Bug#24526),
 		 tell it that the current size is what we want.  */
@@ -8192,18 +8189,27 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 		  f->was_invisible = false;
 		}
 #endif
-	      XSETFRAME (inev.ie.frame_or_window, f);
+	      if (was_iconified)
+		{
+		  SET_FRAME_ICONIFIED (f, false);
+		  inev.ie.kind = DEICONIFY_EVENT;
+		  XSETFRAME (inev.ie.frame_or_window, f);
+		}
 	    }
-	  else if (!not_hidden && !FRAME_ICONIFIED_P (f))
+	  else
 	    {
 	      if (CONSP (frame_size_history))
 		frame_size_history_plain
-		  (f, build_string ("PropertyNotify, hidden & not iconified"));
+		  (f, build_string ("PropertyNotify, hidden"));

 	      SET_FRAME_VISIBLE (f, 0);
-	      SET_FRAME_ICONIFIED (f, true);
-	      inev.ie.kind = ICONIFY_EVENT;
-	      XSETFRAME (inev.ie.frame_or_window, f);
+
+	      if (!was_iconified)
+		{
+		  SET_FRAME_ICONIFIED (f, true);
+		  inev.ie.kind = ICONIFY_EVENT;
+		  XSETFRAME (inev.ie.frame_or_window, f);
+		}
 	    }
 	}

@@ -8402,7 +8408,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       f = x_top_window_to_frame (dpyinfo, event->xmap.window);
       if (f)
         {
-	  bool iconified = FRAME_ICONIFIED_P (f);
+	  bool was_iconified = FRAME_ICONIFIED_P (f);
 	  int value;
 	  bool sticky;
           bool not_hidden = x_get_current_wm_state (f, event->xmap.window, &value, &sticky);
@@ -8410,7 +8416,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 	  if (CONSP (frame_size_history))
 	    frame_size_history_extra
 	      (f,
-	       iconified
+	       was_iconified
 	       ? (not_hidden
 		  ? build_string ("MapNotify, not hidden & iconified")
 		  : build_string ("MapNotify, hidden & iconified"))
@@ -8434,7 +8440,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 #endif /* Not USE_GTK */
 	    }

-	  if (!iconified)
+	  if (!was_iconified)
 	    {
 	      /* The `z-group' is reset every time a frame becomes
 		 invisible.  Handle this here.  */
@@ -8459,13 +8465,13 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 		}
 #endif
 	      f->output_data.x->has_been_visible = true;
-	    }

-          if (not_hidden && iconified)
-            {
-              inev.ie.kind = DEICONIFY_EVENT;
-              XSETFRAME (inev.ie.frame_or_window, f);
-            }
+	      if (was_iconified)
+		{
+		  inev.ie.kind = DEICONIFY_EVENT;
+		  XSETFRAME (inev.ie.frame_or_window, f);
+		}
+	    }
         }
       goto OTHER;

@@ -9354,7 +9360,21 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       f = x_top_window_to_frame (dpyinfo, event->xvisibility.window);
       if (f && (event->xvisibility.state == VisibilityUnobscured
 		|| event->xvisibility.state == VisibilityPartiallyObscured))
-	SET_FRAME_VISIBLE (f, 1);
+	{
+#if defined USE_GTK && defined HAVE_GTK3
+	  /* If GTK3 wants to impose some old size here (Bug#24526),
+	     tell it that the current size is what we want.  */
+	  if (f->was_invisible)
+	    {
+	      xg_frame_set_char_size
+		(f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+	      f->was_invisible = false;
+	    }
+#endif
+	  f->output_data.x->has_been_visible = true;
+	  SET_FRAME_GARBAGED (f);
+	  SET_FRAME_VISIBLE (f, 1);
+	}

       goto OTHER;