Subject: bug#63107: 30.0.50; display-buffer-in-childframe sometimes crashes Emacs on Mac

From: Alan Third <[email-masked]>
Date: Thu, 27 Apr 2023 20:13:14 +0100

On Thu, Apr 27, 2023 at 07:43:54PM +0100, Alan Third wrote:
> On Thu, Apr 27, 2023 at 07:39:06PM +0100, Alan Third wrote:
> > On Thu, Apr 27, 2023 at 06:58:40PM +0200, Daniel Martín wrote:
> > > Yuan Fu <[email-masked]> writes:
> > > 
> > > > X-Debbugs-CC: [email-masked]
> > > >
> > > > Reproduction is pretty easy, just evaluate
> > > >
> > > > (display-buffer-in-child-frame (get-buffer-create "*test*") nil)
> > > >
> > > > Perhaps I'm missing something? Because packages that uses childframe
> > > > like eldoc-box are working fine. I tried using the same ALIST as
> > > > eldoc-box, and various buffers like newly created buffer and current
> > > > buffer, but it always crashes
> > > >
> > > 
> > > This seems to be a regression since Emacs 28.2.
> > 
> > Looks like it's probably the same as bug#55687.
> > 
> > The small patch in that thread might fix this immediate crash, but I
> > expect it will introduce further problems elsewhere.
> 
> OK, so that bug has been closed, but the issue Aaron Jensen ran into
> in that thread appears to have been another issue, the same as this.

Entirely untested patch attached. I can't even try compiling it.

Good luck.
-- 
Alan Third
>From 53e3c6d8004833fd5d64bcb30b0848168fdf7339 Mon Sep 17 00:00:00 2001
From: Alan Third <[email-masked]>
Date: Thu, 27 Apr 2023 20:08:23 +0100
Subject: [PATCH] Fix crash when creating a child frame in NS (bug#63107)

* src/nsterm.m ([EmacsView initFrameFromEmacs:]): Have a second go at
creating the toolbar.
([EmacsWindow createToolbar:]): If there is already a toolbar or the
EmacsView's layer is not an EmacsLayer, then do nothing.
---
 src/nsterm.m | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/src/nsterm.m b/src/nsterm.m
index ecbf80ff72d..2833fc01d14 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -7930,6 +7930,10 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f
   [self setLayerContentsRedrawPolicy:
           NSViewLayerContentsRedrawOnSetNeedsDisplay];
   [self setLayerContentsPlacement:NSViewLayerContentsPlacementTopLeft];
+
+  /* initWithEmacsFrame can't create the toolbar before the layer is
+     set, so have another go at creating the toolbar here.  */
+  [self createToolbar:f];
 #endif
 
   if (ns_drag_types)
@@ -9174,11 +9178,18 @@ - (instancetype) initWithEmacsFrame: (struct frame *) f
 
 - (void)createToolbar: (struct frame *)f
 {
-  if (FRAME_UNDECORATED (f) || !FRAME_EXTERNAL_TOOL_BAR (f))
+  if (FRAME_UNDECORATED (f) || !FRAME_EXTERNAL_TOOL_BAR (f) || [self toolbar] != nil)
     return;
 
   EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f);
 
+#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+  /* If the view's layer isn't an EmacsLayer then we can't create the
+     toolbar yet.  */
+  if (! [[view layer] isKindOfClass:[EmacsLayer class]])
+    return;
+#endif
+
   EmacsToolbar *toolbar = [[EmacsToolbar alloc]
                             initForView:view
                             withIdentifier:[NSString stringWithFormat:@"%p", f]];
-- 
2.39.1