unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Jim Porter <jporterbugs@gmail.com>
To: Gregory Heytings <gregory@heytings.org>
Cc: 51377@debbugs.gnu.org
Subject: bug#51377: Automatically exit server when it has no remaining clients
Date: Sun, 24 Oct 2021 14:40:18 -0700	[thread overview]
Message-ID: <42ff964e-731c-6309-e3e8-e27b14688730@gmail.com> (raw)
In-Reply-To: <b2114244-b9e4-c29f-e272-ba6cb26c5d1b@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 611 bytes --]

On 10/24/2021 12:39 PM, Jim Porter wrote:
> Next, I updated `server-save-buffers-kill-terminal' to check if the 
> server is a lazy daemon and if the current client is the last one: if 
> so, it calls `save-buffers-kill-emacs', which then calls an improved 
> `server-kill-emacs-query-function' that knows to avoid prompting 
> unnecessarily when this is the last client.

I amended the third patch (attached) to account for this change in 
`handle-delete-frame'. This ensures that if you delete the last 
(non-daemon) frame using this method, it calls `save-buffers-kill-emacs' 
to ask the relevant questions.

[-- Attachment #2: 0003-When-killing-the-last-client-attached-to-a-lazy-daem.patch --]
[-- Type: text/plain, Size: 5379 bytes --]

From 767b43cc04f42f36db20fa1ef9b32aab2c37b497 Mon Sep 17 00:00:00 2001
From: Jim Porter <jporterbugs@gmail.com>
Date: Sun, 24 Oct 2021 12:11:37 -0700
Subject: [PATCH 3/3] When killing the last client attached to a lazy daemon,
 kill the daemon too

lisp/server.el (server-save-buffers-kill-terminal): Kill Emacs when
connected to a lazy daemon and there are no other clients.
(server-kill-emacs-query-function): Don't warn about killing Emacs
when not necessary.
lisp/frame.el (handle-delete-frame): Exclude the initial frame of a
lazily-created daemon as a "valid" other frame.
---
 lisp/frame.el  |  7 ++++--
 lisp/server.el | 61 +++++++++++++++++++++++++++++---------------------
 2 files changed, 40 insertions(+), 28 deletions(-)

diff --git a/lisp/frame.el b/lisp/frame.el
index dfbd751201..fd38c4b623 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -119,11 +119,14 @@ handle-delete-frame
     (if (catch 'other-frame
           (dolist (frame-1 (frame-list))
             ;; A valid "other" frame is visible, has its `delete-before'
-            ;; parameter unset and is not a child frame.
+            ;; parameter unset and is not a child frame or the initial frame
+            ;; of a lazily-created daemon.
             (when (and (not (eq frame-1 frame))
                        (frame-visible-p frame-1)
                        (not (frame-parent frame-1))
-                       (not (frame-parameter frame-1 'delete-before)))
+                       (not (frame-parameter frame-1 'delete-before))
+                       (or (not (eq (daemon-type) 'lazy))
+                           (frame-parameter frame-1 'client)))
               (throw 'other-frame t))))
 	(delete-frame frame t)
       ;; Gildea@x.org says it is ok to ask questions before terminating.
diff --git a/lisp/server.el b/lisp/server.el
index 5988560c83..0cbabba621 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -1580,12 +1580,17 @@ server-done
     (server-buffer-done (current-buffer))))
 
 (defun server-kill-emacs-query-function ()
-  "Ask before exiting Emacs if it has live clients."
-  (or (not (seq-some (lambda (proc)
-                       (seq-some #'buffer-live-p
-                                 (process-get proc 'buffers)))
-                     server-clients))
-      (yes-or-no-p "This Emacs session has clients; exit anyway? ")))
+  "Ask before exiting Emacs if it has live clients.
+If Emacs was started as a lazy daemon and the only live client is the
+current frame's client, don't bother asking."
+  (let ((ignored-proc (and (eq (daemon-type) 'lazy)
+                           (frame-parameter nil 'client))))
+    (or (not (seq-some (lambda (proc)
+                         (unless (eq ignored-proc proc)
+                           (seq-some #'buffer-live-p
+                                     (process-get proc 'buffers))))
+                       server-clients))
+        (yes-or-no-p "This Emacs session has clients; exit anyway? "))))
 
 (defun server-kill-buffer ()
   "Remove the current buffer from its clients' buffer list.
@@ -1721,28 +1726,32 @@ server-save-buffers-kill-terminal
 With ARG non-nil, silently save all file-visiting buffers, then kill.
 
 If emacsclient was started with a list of filenames to edit, then
-only these files will be asked to be saved."
+only these files will be asked to be saved.
+
+If Emacs was started as a lazy daemon and this is the last client
+connected to it, this will call `save-buffers-kill-emacs'."
   (let ((proc (frame-parameter nil 'client)))
-    (cond ((eq proc 'nowait)
+    (unless (or (eq proc 'nowait) (processp proc))
+      (error "Invalid client frame"))
+    (if (and (eq (daemon-type) 'lazy)
+             (equal server-clients (unless (eq proc 'nowait) (list proc))))
+        ;; If we're the last client connected to a lazy daemon, kill Emacs.
+        (save-buffers-kill-emacs arg)
+      (if (eq proc 'nowait)
 	   ;; Nowait frames have no client buffer list.
-	   (if (cdr (frame-list))
-	       (progn (save-some-buffers arg)
-		      (delete-frame))
-	     ;; If we're the last frame standing, kill Emacs.
-	     (save-buffers-kill-emacs arg)))
-	  ((processp proc)
-	   (let ((buffers (process-get proc 'buffers)))
-	     (save-some-buffers
-	      arg (if buffers
-                      ;; Only files from emacsclient file list.
-		      (lambda () (memq (current-buffer) buffers))
-                    ;; No emacsclient file list: don't override
-                    ;; `save-some-buffers-default-predicate' (unless
-                    ;; ARG is non-nil), since we're not killing
-                    ;; Emacs (unlike `save-buffers-kill-emacs').
-		    (and arg t)))
-	     (server-delete-client proc)))
-	  (t (error "Invalid client frame")))))
+	  (progn (save-some-buffers arg)
+		 (delete-frame))
+        (let ((buffers (process-get proc 'buffers)))
+	  (save-some-buffers
+	   arg (if buffers
+                   ;; Only files from emacsclient file list.
+		   (lambda () (memq (current-buffer) buffers))
+                 ;; No emacsclient file list: don't override
+                 ;; `save-some-buffers-default-predicate' (unless ARG
+                 ;; is non-nil), since we're not killing Emacs (unlike
+                 ;; `save-buffers-kill-emacs').
+		 (and arg t)))
+	  (server-delete-client proc))))))
 
 (define-key ctl-x-map "#" 'server-edit)
 
-- 
2.25.1


      parent reply	other threads:[~2021-10-24 21:40 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-24 15:15 bug#51377: Automatically exit server when it has no remaining clients Gregory Heytings
2021-10-24 16:03 ` Jim Porter
2021-10-24 16:14   ` Jim Porter
2021-10-24 16:32   ` Gregory Heytings
2021-10-24 18:08     ` Jim Porter
2021-10-24 18:43       ` Gregory Heytings
2021-10-24 19:39         ` Jim Porter
2021-10-24 20:42           ` Gregory Heytings
2021-10-24 21:19             ` Jim Porter
2021-10-24 21:37               ` Gregory Heytings
2021-10-25 18:21                 ` Jim Porter
2021-10-26 10:37                   ` Gregory Heytings
2021-10-26 11:59                     ` Gregory Heytings
2021-10-26 15:07                       ` Gregory Heytings
2021-11-11  5:43                         ` Lars Ingebrigtsen
2021-10-24 21:40           ` Jim Porter [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=42ff964e-731c-6309-e3e8-e27b14688730@gmail.com \
    --to=jporterbugs@gmail.com \
    --cc=51377@debbugs.gnu.org \
    --cc=gregory@heytings.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).