Subject: bug#72517: 31.0.50; [PATCH] Close X connection upon deletion of last emacsclient frame

From: Thomas Fitzsimmons <[email-masked]>
Date: Wed, 07 Aug 2024 20:47:48 -0400

Hi,

The attached patch fixes an issue reported on the mailing list [1].
After quitting a remote "emacsclient -c" frame using C-x 5 0, the SSH
session will hang on exit.  It is waiting for the X11 display connection
to be closed, but Emacs never closes it.

I have been using this patch for a few months without issue, with the
Lucid toolkit, running "emacsclient -c" over a remote X11 connection.

I just retested it on master (423c86cbde7b1ed1d42c7e21fef6e8be872857b0)
with "./configure --with-x-toolkit=lucid" and it works for me.

I would like others who use remote X11 emacsclient to try the patch, to
make sure it does not introduce crashes, error messages or warnings.  If
it works for others, I can push the patch to master.

Thomas

1. https://lists.gnu.org/archive/html/emacs-devel/2020-04/msg00950.html

>From 27496ab740722d2246ecec1ffbb7f7390d081873 Mon Sep 17 00:00:00 2001
From: Thomas Fitzsimmons <[email-masked]>
Date: Wed, 7 Aug 2024 19:46:04 -0400
Subject: [PATCH] Close X connection upon deletion of last emacsclient frame

This fixes an issue reported on the mailing list:
https://lists.gnu.org/archive/html/emacs-devel/2020-04/msg00950.html

* lisp/server.el (server-handle-delete-frame): If the frame is an
X frame and DISPLAY is set, close the X connection to the display.
---
 lisp/server.el | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/lisp/server.el b/lisp/server.el
index abfd3d4d753..6f39ae651c7 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -510,7 +510,13 @@ server-handle-delete-frame
                             (eq proc (frame-parameter f 'client))))
                      (frame-list))))
       (server-log (format "server-handle-delete-frame, frame %s" frame) proc)
-      (server-delete-client proc 'noframe)))) ; Let delete-frame delete the frame later.
+      (server-delete-client proc 'noframe) ; Let delete-frame delete the frame later.
+      ;; Close the X connection next time the main loop becomes idle.
+      ;; This prevents an SSH session from hanging after exiting a
+      ;; remote "emacsclient -c" frame via C-x 5 0.
+      (let ((display (frame-parameter frame 'display)))
+	(when (and display (eq (framep frame) 'x))
+	  (run-at-time nil nil (lambda () (x-close-connection display))))))))
 
 (defun server-handle-suspend-tty (terminal)
   "Notify the client process that its tty device is suspended."
-- 
2.39.2