bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#51993: 29.0.50; [PATCH explanation] Killing emacsclient terminal wit


From: Jim Porter
Subject: bug#51993: 29.0.50; [PATCH explanation] Killing emacsclient terminal with `server-stop-automatically' doesn't prompt to save files
Date: Thu, 1 Dec 2022 17:42:18 -0800

On 12/1/2022 9:29 AM, Eli Zaretskii wrote:
I'm okay with installing the original changes on master, if you indeed
believe the new code is much cleaner (but then please explain why you think
so, because I don't think I see that just by looking at the diffs).  But for
the release branch, I'm not comfortable with making such serious changes in
a part of server.el that is already way too complicated, what with all the
fancy shutdown options we strive to support.  There be dragons, and I have
no intention to release Emacs 29 with buggy server-client editing.  So for
the release branch, please prepare a safer version of the change, which only
changes the code which is the immediate cause of the incorrect behavior.

Attached is a patch series that explains in more detail how I arrived at the previous version of my patch. This is basically a reconstruction of the steps I took when writing it originally. I'll describe my overall plan and then address the specific comments you had after that. (This might be overly-verbose, but I wanted to put as much detail in as I could in the hopes of addressing all your concerns.)

Prior to my patch, 'server-stop-automatically--handle-delete-frame' (henceforth 'SSA--handle-delete-frame') can get called in two situations: when someone calls 'delete-frame' (it's a hook on 'delete-frame-functions') or when someone calls 'save-buffers-kill-emacs' ('server-save-buffers-kill-emacs' delegates to it when configured to). To help make the logic easier to follow, I split it into two: one for handling 'delete-frame', and one for handling 'save-buffers-kill-terminal'. See patches 0001 and 0002.

 (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))))

And here you completely rewrote a function.

In patch 0002, you can see (most of) this change that you mentioned: since I made one function for each case as described above, the second 'if' statement's conditional is always false, so I just got rid of the conditional and the then-clause, leaving only the else-clause: (null (cddr (frame-list))). I also simplified this function a bit in the last patch, 0007.

Now for the rest of the patch series.

The original bug is that the behavior of 'server-save-buffers-kill-terminal' when there are multiple clients should be the same regardless of the SSA setting (it wasn't). So next, I made 'SSA--handle-kill-terminal' have the same basic structure as 'server-save-buffers-kill-terminal' (patch 0003). That makes it easier to see the differences between the two.

Patch 0005 is where the real fix is: it makes sure that when we *don't* want to kill Emacs, 'SSA--handle-kill-terminal' does the same thing as 'server-save-buffers-kill-terminal'.

@@ -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")))))

But this one is problematic: it adds save-buffers-kill-emacs which wasn't in
the original code, and I don't understand why.  The bug wasn't about this,
was it?

In patch 0005, you can start to see this block of code take shape: because we want to handle the "don't kill Emacs" case in 'SSA--handle-kill-terminal', we add the 'save-some-buffers' + 'server-delete-client' code there, resulting in something that looks similar to the above hunk.

Then, in patch 0006, I just merge 'server-save-buffers-kill-terminal' and 'SSA--handle-kill-terminal', since most of the code is shared at this point. Finally, patch 0007 is just a bit of cleanup; with all of these applied, server.el should be identical to my previous patch.

Hopefully this explains things reasonably well, and doesn't go into too much (or too little) detail. If there are any other bits that you have concerns about, just let me know.

Attachment: 0001-Duplicate-server-stop-automatically-handle-delete-fr.patch
Description: Text document

Attachment: 0002-Simplify-server-stop-automatically-handlers.patch
Description: Text document

Attachment: 0003-Restructure-server-stop-automatically-handle-kill-te.patch
Description: Text document

Attachment: 0004-Remove-unnecessary-delete-frame-calls-after-save-buf.patch
Description: Text document

Attachment: 0005-This-is-the-commit-that-actually-fixes-bug-51993.patch
Description: Text document

Attachment: 0006-Merge-kill-terminal-implementations.patch
Description: Text document

Attachment: 0007-Simplify-server-stop-automatically-handle-delete-fra.patch
Description: Text document


reply via email to

[Prev in Thread] Current Thread [Next in Thread]