Subject: 29.0.50; [PATCH] When killing Emacs from a client frame with no other frames, Emacs shows a useless error prompt

From: Jim Porter <[email-masked]>
Date: Sat, 29 Oct 2022 14:33:42 -0700

(Note: I originally mentioned this in bug#51993, but it's only 
somewhat-related to that bug. To make things easier to follow, I pulled 
this part out into a separate bug.)

To see this in action:

   $ emacs -Q -f server-start
   $ emacsclient -c foo.txt

   ;; From the first (non-client) frame:
   C-x 5 0  ;; delete-frame

   ;; From the second (client) frame:
   M-x kill-emacs
   ;; Emacs prompts:
   Error (error Attempt to delete the sole visible or iconified frame); 
continue? (y or n)

Pressing "y" will properly kill Emacs, but there's no real use for the 
warning in this case. It happens because 'server-force-stop' 
(indirectly) tries to delete the last (client) frame before killing 
Emacs, meaning that Emacs would have zero frames for a bit.

Since 'server-force-stop's docstring says, "This function is meant to be 
called from `kill-emacs-hook'," it should be safe to have 
'server-force-stop' avoid deleting any frames: they'll just get deleted 
when Emacs is actually killed.

Attached is a patch to do this. Note that I named the new argument 
"noframe" because that matches the existing code in server.el (see 
'server-delete-client'). It's a bit of a misnomer though, and maybe 
"keep-frames" would be better...

From 522574ce69e3c198a40b57e2e211e14562334f33 Mon Sep 17 00:00:00 2001
From: Jim Porter <[email-masked]>
Date: Fri, 19 Nov 2021 20:14:33 -0800
Subject: [PATCH] Don't explicitly delete client frames when killing Emacs
 anyway

This eliminates a useless error prompt when killing Emacs from a
client frame when there are no other frames.

* lisp/server.el (server-start): Add NOFRAME argument to avoid
deleting frames.
(server-force-stop): Pass 'noframe' to 'server-stop'.
---
 lisp/server.el | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/lisp/server.el b/lisp/server.el
index 90d97c1538..2b7213b890 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -611,7 +611,7 @@ server-get-auth-key
     (server-generate-key)))
 
 ;;;###autoload
-(defun server-start (&optional leave-dead inhibit-prompt)
+(defun server-start (&optional leave-dead inhibit-prompt noframe)
   "Allow this Emacs process to be a server for client processes.
 This starts a server communications subprocess through which client
 \"editors\" can send your editing commands to this Emacs job.
@@ -625,6 +625,11 @@ server-start
 running, ask the user for confirmation first, unless optional
 argument INHIBIT-PROMPT is non-nil.
 
+If NOFRAME is non-nil, don't delete any existing frames
+associated with a client process.  This is useful, for example,
+when killing Emacs, in which case the frames will get deleted
+anyway.
+
 To force-start a server, do \\[server-force-delete] and then
 \\[server-start].
 
@@ -683,7 +688,7 @@ server-start
          (setq leave-dead t)))
       ;; If this Emacs already had a server, clear out associated status.
       (while server-clients
-	(server-delete-client (car server-clients)))
+	(server-delete-client (car server-clients) noframe))
       ;; Now any previous server is properly stopped.
       (if leave-dead
 	  (progn
@@ -742,7 +747,7 @@ server-start
 (defun server-force-stop ()
   "Kill all connections to the current server.
 This function is meant to be called from `kill-emacs-hook'."
-  (server-start t t))
+  (server-start t t 'noframe))
 
 ;;;###autoload
 (defun server-force-delete (&optional name)
-- 
2.25.1