Subject: bug#78980: 31.0.50; C-z crashes emacsclient -nw

From: martin rudalics <[email-masked]>
Date: Thu, 10 Jul 2025 18:19:53 +0200

> Than I guess I've simply not understood what's going on. Or maybe the
 > problem is that a call to frame_redisplay_p is missing in
 > redisplay_interlal, where is_tty_root_frame_with_visible_child is
 > called?

No.  It was a simple bug in frame_redisplay_p which disregarded the
visibility of the argument frame on ttys.  Normally, the tty top frame
is always visible - it isn't after 'suspend-tty' does

	  SET_FRAME_VISIBLE (root_frame (top), false);

BTW my last patch was wrong again, the below one should work.

martin

diff --git a/src/frame.c b/src/frame.c
index 70e200d9219..714a786a29b 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -358,36 +358,29 @@ DEFUN ("window-system", Fwindow_system, Swindow_system, 0, 1, 0,
  }

  /** Return true if F can be redisplayed, that is if F is visible and, if
-    F is a tty frame, all its ancestors are visible too.  */
+    F is a tty frame, all its ancestors are visible too and F's root
+    frame is its terminal's top frame..  */
  bool
  frame_redisplay_p (struct frame *f)
  {
    if (is_tty_frame (f))
      {
-      struct frame *p = FRAME_PARENT_FRAME (f);
-      struct frame *q = NULL;
+      struct tty_display_info *tty = FRAME_TTY (f);
+      struct frame *r = XFRAME (tty->top_frame);

-      while (p)
+      while (f)
  	{
-	  if (!p->visible)
+	  if (!f->visible)
  	    /* A tty child frame cannot be redisplayed if one of its
  	       ancestors is invisible.  */
  	    return false;
+	  else if (f == r)
+	    return true;
  	  else
-	    {
-	      q = p;
-	      p = FRAME_PARENT_FRAME (p);
-	    }
+	    f = FRAME_PARENT_FRAME (f);
  	}

-      struct tty_display_info *tty = FRAME_TTY (f);
-      struct frame *r = XFRAME (tty->top_frame);
-
-      /* A tty child frame can be redisplayed iff its root is the top
-	 frame of its terminal.  Any other tty frame can be redisplayed
-	 iff it is the top frame of its terminal itself which must be
-	 always visible.  */
-      return (q ? q == r : f == r);
+      return false;
      }
    else
  #ifndef HAVE_X_WINDOWS