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
prev 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).