Subject: Re: bug#21357: 24.5; Daemon leaves Mac OSX App open after closing GUI frame

From: Alan Third <[email-masked]>
Date: Wed, 25 Aug 2021 21:18:51 +0100

On Mon, Aug 16, 2021 at 06:13:03PM +0100, Alan Third wrote:
> On Mon, Aug 16, 2021 at 02:57:58PM +0200, Lars Ingebrigtsen wrote:
> > [email-masked] writes:
> > 
> > > If I have Emacs (OSX App) started in daemon mode, and then create a
> > > GUI frame, e.g. emacsclient -c, an instance of Emacs.app starts,
> > > which then does not go away when the frame is closed with C-x C-c.
> > > Most menu items, even ones such as "New Frame (C-x 5 2)" that seem
> > > like they should make sense without a frame, are unresponsive.
> > 
> > (I'm going through old bug reports that unfortunately weren't
> > resolved at the time.)
> > 
> > Is this problem still present in recent Emacs versions?
> 
> As far as I'm aware it is.

The attached patch "fixes" this by hiding the app icon in the dock and
removing the menus. It's still possible to create a new frame using
emacsclient.

There's still a bug when a terminal frame is open and the last GUI
frame is closed. I've put the code in ns_delete_terminal, which may
not be the best place. Perhaps it should go in the normal frame
closing function and check whether there are any remaining open
frames.

The alternative is to occasionally run the NS run loop even when there
are no NS frames open. I don't know how we could do that but it would
allow us to leave the menu and dock icon available and operative even
without any GUI frames open.
-- 
Alan Third
>From 5dd66d7966d32e8c42e12e16b8682c52d4487d81 Mon Sep 17 00:00:00 2001
From: Alan Third <[email-masked]>
Date: Wed, 25 Aug 2021 21:00:07 +0100
Subject: [PATCH] Disable the NS app when no frames are left (bug#14619,
 bug#21357, bug#23586)

* src/nsfns.m (Fx_create_frame): Enable the app.
* src/nsterm.m (ns_delete_terminal): Disable the app.
---
 src/nsfns.m  | 5 +++++
 src/nsterm.m | 6 ++++++
 2 files changed, 11 insertions(+)

diff --git a/src/nsfns.m b/src/nsfns.m
index c40367703d..07bcab1816 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -1343,6 +1343,11 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
 
   f->output_data.ns->in_animation = NO;
 
+#ifdef NS_IMPL_COCOA
+  /* If the app has previously been disabled, start it up again.  */
+  [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
+#endif
+
   [[EmacsView alloc] initFrameFromEmacs: f];
 
   ns_icon (f, parms);
diff --git a/src/nsterm.m b/src/nsterm.m
index 1c1f0c8f23..4bdc67c10b 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -5014,6 +5014,12 @@ static Lisp_Object ns_string_to_lispmod (const char *s)
 
   block_input ();
 
+#ifdef NS_IMPL_COCOA
+  /* Rather than try to clean up the NS environment we can just
+     disable the app and leave it waiting for any new frames.  */
+  [NSApp setActivationPolicy:NSApplicationActivationPolicyProhibited];
+#endif
+
   image_destroy_all_bitmaps (dpyinfo);
   ns_delete_display (dpyinfo);
   unblock_input ();
-- 
2.30.2