]> git.eshelyaron.com Git - emacs.git/commitdiff
Enforce redisplay when deleting a child frame (bug#76406)
authorGerd Möllmann <gerd.moellmann@gmail.com>
Sun, 23 Feb 2025 04:07:55 +0000 (05:07 +0100)
committerEshel Yaron <me@eshelyaron.com>
Wed, 26 Feb 2025 09:31:40 +0000 (10:31 +0100)
* src/term.c (tty_free_frame_resources): When deleting a child mark its
root frame to garbaged.
* src/dispnew.c (prepare_desired_root_row): Add a check for GLYPH_DEBUG.

(cherry picked from commit 2a756ce9d774a91774fdf4c5cd40562540a40633)

src/dispnew.c
src/term.c

index e5070d4554deac4bc0bcd0c9573305f84d6ef31b..f7dbeb22b402618d231e1b0f546aa01fd1ec1c4a 100644 (file)
@@ -3522,12 +3522,22 @@ prepare_desired_root_row (struct frame *root, int y)
     return desired_row;
 
   /* If we have a current row that is up to date, copy that to the
-     desired row and use that.  */
-  /* Don't copy rows that aren't enabled, in particuler because they
-     might not have the 'frame' member of glyphs set.  */
+     desired row and use that.  Don't copy rows that are bot enabled, in
+     particular because they might not have the 'frame' member of glyphs
+     set.  */
   struct glyph_row *current_row = MATRIX_ROW (root->current_matrix, y);
   if (current_row->enabled_p)
     {
+# ifdef GLYPH_DEBUG
+      /* Safety belt: Try to make sure that we don't copy glyphs from a
+         stale current matrix that contains glyphs referring to dead
+         frames. */
+      for (int i = 0; i < current_row->used[TEXT_AREA]; ++i)
+       {
+         struct glyph *glyph = current_row->glyphs[TEXT_AREA] + i;
+         eassert (glyph->frame && FRAME_LIVE_P (glyph->frame));
+       }
+# endif
       memcpy (desired_row->glyphs[0], current_row->glyphs[0],
              root->current_matrix->matrix_w * sizeof (struct glyph));
       desired_row->enabled_p = true;
index fd95e75a0074cef4e82402cfcaeb4ea9fb53ffe9..ba7b14de1589c216588ee92e0fc43c45a2c745b2 100644 (file)
@@ -4077,7 +4077,8 @@ create_tty_output (struct frame *f)
   f->output_data.tty = t;
 }
 
-/* Delete frame F's face cache, and its tty-dependent part.  */
+/* Delete frame F's face cache, and its tty-dependent part.  This is
+   installed as a delete_frame_hook.  */
 
 static void
 tty_free_frame_resources (struct frame *f)
@@ -4085,6 +4086,11 @@ tty_free_frame_resources (struct frame *f)
   eassert (FRAME_TERMCAP_P (f));
   free_frame_faces (f);
   xfree (f->output_data.tty);
+
+  /* Deleting a child frame means we have to thoroughly redisplay its
+     root frame to make sure the child disappears from the display.  */
+  if (FRAME_PARENT_FRAME (f))
+    SET_FRAME_GARBAGED (root_frame (f));
 }
 
 #elif defined MSDOS