From: Jim Porter <jporterbugs@gmail.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: larsi@gnus.org, 51993@debbugs.gnu.org, gregory@heytings.org
Subject: bug#51993: 29.0.50; [PATCH] Killing emacsclient terminal with `server-stop-automatically' doesn't prompt to save files
Date: Mon, 28 Nov 2022 21:31:02 -0800 [thread overview]
Message-ID: <b7c81fd1-76ae-1054-a4be-229ac7e16c9b@gmail.com> (raw)
In-Reply-To: <ca35534e-5598-3b47-b180-a67da670ea82@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1404 bytes --]
On 10/24/2022 8:10 PM, Jim Porter wrote:
> On 10/21/2022 11:57 PM, Eli Zaretskii wrote:
>>> Date: Fri, 21 Oct 2022 20:46:47 -0700
>>> Cc: larsi@gnus.org, 51993@debbugs.gnu.org, gregory@heytings.org
>>> From: Jim Porter <jporterbugs@gmail.com>
>>>
>>> The issue in the quote above is that if you enable automatic server
>>> shutdown in Emacs 29, it changes the behavior of exiting an emacsclient
>>> even when it wouldn't stop the server (i.e. when there are other active
>>> clients). That's surprising to me, I wouldn't expect that setting to
>>> affect cases when it decides *not* to kill the Emacs daemon.
>>
>> Sounds like a bug to me, because it contradicts what the doc string
>> says.
>
> That's how it seems to me too. ...
Ok, after quite a delay, here's a patch for this. Previously, the
function 'server-stop-automatically--handle-delete-frame' responded to
both 'C-x C-c' ('save-buffers-kill-terminal') and 'delete-frame', which
made it more complex. I've moved the 'C-x C-c' case into
'server-save-buffers-kill-terminal', which simplifies
'server-stop-automatically--handle-delete-frame'.
The updated 'server-save-buffers-kill-terminal' should now make sure
that the new stop-automatically behavior only happens when there are no
other client processes (or nowait frames).
I've also attached a version of the diff excluding the whitespace
changes to make reviewing the code easier.
[-- Attachment #2: 0001-Make-killing-a-non-last-client-work-the-same-no-matt.patch --]
[-- Type: text/plain, Size: 5307 bytes --]
From 2c0940a86cd11ebad0d1ea7fcf8fe2e9cfbc0fb3 Mon Sep 17 00:00:00 2001
From: Jim Porter <jporterbugs@gmail.com>
Date: Mon, 28 Nov 2022 21:17:59 -0800
Subject: [PATCH] Make killing a non-last client work the same no matter the
auto-stop setting
Previously, if 'server-stop-automatically' was configured for
'kill-terminal' or 'delete-frame', killing a client via
'save-buffers-kill-terminal' wouldn't prompt about the saving files in
the client's buffer list (as it does when not using those settings).
This change ensures that those settings only apply when killing the
last client, as described in the manual (bug#51993).
* lisp/server.el (server-save-buffers-kill-terminal): Handle
'server-stop-automatically' behavior in this function, rather than
calling 'server-stop-automatically--handle-delete-frame'.
(server-stop-automatically--handle-delete-frame): Remove code that
handled the 'save-buffers-kill-terminal' case.
---
lisp/server.el | 83 ++++++++++++++++++++++++--------------------------
1 file changed, 40 insertions(+), 43 deletions(-)
diff --git a/lisp/server.el b/lisp/server.el
index 1b027f88ce..e88cffa8fb 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -1780,52 +1780,49 @@ server-save-buffers-kill-terminal
If emacsclient was started with a list of filenames to edit, then
only these files will be asked to be saved."
- (if server-stop-automatically
- (server-stop-automatically--handle-delete-frame (selected-frame))
- (let ((proc (frame-parameter nil 'client)))
- (cond ((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"))))))
+ (let ((proc (frame-parameter nil 'client)))
+ (cond ((eq proc 'nowait)
+ ;; Nowait frames have no client buffer list.
+ (if (length> (frame-list) (if server-stop-automatically 2 1))
+ ;; If there are any other frames, only delete this one.
+ ;; When `server-stop-automatically' is set, don't count
+ ;; the daemon frame.
+ (progn (save-some-buffers arg)
+ (delete-frame))
+ ;; If we're the last frame standing, kill Emacs.
+ (save-buffers-kill-emacs arg)))
+ ((processp proc)
+ (if (or (not server-stop-automatically)
+ (length> server-clients 1)
+ (seq-some
+ (lambda (frame)
+ (when-let ((p (frame-parameter frame 'client)))
+ (not (eq proc p))))
+ (frame-list)))
+ (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))
+ ;; If `server-stop-automatically' is set, there are no
+ ;; other client processes, and no other client frames
+ ;; (e.g. `nowait' frames), kill Emacs.
+ (save-buffers-kill-emacs arg)))
+ (t (error "Invalid client frame")))))
(defun server-stop-automatically--handle-delete-frame (frame)
"Handle deletion of FRAME when `server-stop-automatically' is used."
- (when server-stop-automatically
- (if (if (and (processp (frame-parameter frame 'client))
- (eq this-command 'save-buffers-kill-terminal))
- (progn
- (dolist (f (frame-list))
- (when (and (eq (frame-parameter frame 'client)
- (frame-parameter f 'client))
- (not (eq frame f)))
- (set-frame-parameter f 'client nil)
- (let ((server-stop-automatically nil))
- (delete-frame f))))
- (if (cddr (frame-list))
- (let ((server-stop-automatically nil))
- (delete-frame frame)
- nil)
- t))
- (null (cddr (frame-list))))
- (let ((server-stop-automatically nil))
- (save-buffers-kill-emacs)
- (delete-frame frame)))))
+ (when (and server-stop-automatically
+ (null (cddr (frame-list))))
+ (let ((server-stop-automatically nil))
+ (save-buffers-kill-emacs)
+ (delete-frame frame))))
(defun server-stop-automatically--maybe-kill-emacs ()
"Handle closing of Emacs daemon when `server-stop-automatically' is used."
--
2.25.1
[-- Attachment #3: no-whitespace-change.diff --]
[-- Type: text/plain, Size: 3078 bytes --]
diff --git a/lisp/server.el b/lisp/server.el
index 1b027f88ce..e88cffa8fb 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -1780,17 +1780,25 @@ server-save-buffers-kill-terminal
If emacsclient was started with a list of filenames to edit, then
only these files will be asked to be saved."
- (if server-stop-automatically
- (server-stop-automatically--handle-delete-frame (selected-frame))
(let ((proc (frame-parameter nil 'client)))
(cond ((eq proc 'nowait)
;; Nowait frames have no client buffer list.
- (if (cdr (frame-list))
+ (if (length> (frame-list) (if server-stop-automatically 2 1))
+ ;; If there are any other frames, only delete this one.
+ ;; When `server-stop-automatically' is set, don't count
+ ;; the daemon frame.
(progn (save-some-buffers arg)
(delete-frame))
;; If we're the last frame standing, kill Emacs.
(save-buffers-kill-emacs arg)))
((processp proc)
+ (if (or (not server-stop-automatically)
+ (length> server-clients 1)
+ (seq-some
+ (lambda (frame)
+ (when-let ((p (frame-parameter frame 'client)))
+ (not (eq proc p))))
+ (frame-list)))
(let ((buffers (process-get proc 'buffers)))
(save-some-buffers
arg (if buffers
@@ -1801,31 +1809,20 @@ server-save-buffers-kill-terminal
;; 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"))))))
+ (server-delete-client proc))
+ ;; If `server-stop-automatically' is set, there are no
+ ;; other client processes, and no other client frames
+ ;; (e.g. `nowait' frames), kill Emacs.
+ (save-buffers-kill-emacs arg)))
+ (t (error "Invalid client frame")))))
(defun server-stop-automatically--handle-delete-frame (frame)
"Handle deletion of FRAME when `server-stop-automatically' is used."
- (when server-stop-automatically
- (if (if (and (processp (frame-parameter frame 'client))
- (eq this-command 'save-buffers-kill-terminal))
- (progn
- (dolist (f (frame-list))
- (when (and (eq (frame-parameter frame 'client)
- (frame-parameter f 'client))
- (not (eq frame f)))
- (set-frame-parameter f 'client nil)
- (let ((server-stop-automatically nil))
- (delete-frame f))))
- (if (cddr (frame-list))
- (let ((server-stop-automatically nil))
- (delete-frame frame)
- nil)
- t))
+ (when (and server-stop-automatically
(null (cddr (frame-list))))
(let ((server-stop-automatically nil))
(save-buffers-kill-emacs)
- (delete-frame frame)))))
+ (delete-frame frame))))
(defun server-stop-automatically--maybe-kill-emacs ()
"Handle closing of Emacs daemon when `server-stop-automatically' is used."
next prev parent reply other threads:[~2022-11-29 5:31 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-20 4:29 bug#51993: 29.0.50; [PATCH] Killing emacsclient terminal with `server-stop-automatically' doesn't prompt to save files Jim Porter
2021-11-20 7:13 ` Eli Zaretskii
2021-11-23 9:48 ` Gregory Heytings
2021-11-23 18:25 ` Jim Porter
2021-11-23 20:37 ` Gregory Heytings
2021-11-23 22:08 ` Jim Porter
2021-11-23 22:49 ` Gregory Heytings
2021-11-23 23:42 ` Jim Porter
2021-11-23 23:59 ` Gregory Heytings
2021-11-24 1:10 ` Jim Porter
2021-11-29 5:39 ` Jim Porter
2021-11-29 12:41 ` Eli Zaretskii
2021-11-29 13:40 ` Gregory Heytings
2021-11-29 19:31 ` Jim Porter
2022-01-01 0:11 ` Jim Porter
2022-09-09 17:55 ` Lars Ingebrigtsen
2022-09-09 18:04 ` Jim Porter
2022-10-09 22:09 ` Jim Porter
2022-10-10 6:04 ` Eli Zaretskii
2022-10-20 3:14 ` Jim Porter
2022-10-20 6:23 ` Eli Zaretskii
2022-10-21 5:51 ` Jim Porter
2022-10-21 6:38 ` Eli Zaretskii
2022-10-22 3:46 ` Jim Porter
2022-10-22 6:57 ` Eli Zaretskii
2022-10-25 3:10 ` Jim Porter
2022-10-30 22:32 ` Jim Porter
2022-11-29 5:31 ` Jim Porter [this message]
2022-12-01 17:29 ` Eli Zaretskii
2022-12-02 1:09 ` bug#51993: 29.0.50; [PATCH for 29.1] " Jim Porter
2022-12-02 14:10 ` Eli Zaretskii
2022-12-02 21:33 ` Jim Porter
2022-12-04 17:56 ` Eli Zaretskii
2022-12-04 22:26 ` Jim Porter
2022-12-06 22:20 ` Jim Porter
2022-12-02 1:42 ` bug#51993: 29.0.50; [PATCH explanation] " Jim Porter
2022-12-02 14:31 ` Eli Zaretskii
2021-11-29 19:12 ` bug#51993: 29.0.50; [PATCH] " Jim Porter
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=b7c81fd1-76ae-1054-a4be-229ac7e16c9b@gmail.com \
--to=jporterbugs@gmail.com \
--cc=51993@debbugs.gnu.org \
--cc=eliz@gnu.org \
--cc=gregory@heytings.org \
--cc=larsi@gnus.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).