Subject: bug#37826: Very annoying autoraise client/server behavior with -t option

From: Carlos Pita <[email-masked]>
Date: Mon, 21 Oct 2019 15:40:13 -0300

Here is some preliminary work. The patch suppresses messages from
server-visit-files.

Some remarks:

1. Perhaps I'd have preferred to advice only around
find-file-noselect, but this would probably require using a global
variable to pass delayed messages from server-visit-files to
server-execute. Thus I wrapped the entire server-visit-files call and
keep the messages local to server-execute.

2. Also I'd have liked that the mock message function returned the
formatted message (since it's part of the interface) but there are
some corner cases (nil, non-string, empty first parameter) that force
me to replicate much of the actual implementation (Fmessage), which I
dislike.

3. I'm dumping the delayed messages in an environment with `(or frame
(selected-frame))` selected frame. The last `((not (null buffers))`
guard in the case statement that comes after my change suggests that
indeed `frame` might be nil, so I'm being careful and fallbacking to
the selected frame in that case. Now, there might be no frame at all,
but then I fail to see what else can be done.

I'm rather open to change any of the above points.

diff --git a/lisp/server.el b/lisp/server.el
index 45fa55ad6b..5943a9ddca 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -1304,7 +1304,14 @@ server-execute
   ;; including code that needs to wait.
   (with-local-quit
     (condition-case err
-        (let* ((buffers (server-visit-files files proc nowait))
+        (let* (;; Delay messages to avoid auto raising frame (Bug#37826).
+               (messages nil)
+               (delay (lambda (fun &rest args) (push args messages)))
+               (buffers (unwind-protect
+                            (progn
+                              (advice-add #'message :around delay)
+                              (server-visit-files files proc nowait))
+                          (advice-remove #'message delay)))
                ;; If we were told only to open a new client, obey
                ;; `initial-buffer-choice' if it specifies a file
                ;; or a function.
@@ -1325,6 +1332,10 @@ server-execute
                           ;; Switch to initial buffer in case the
frame was reused.
                           (when initial-buffer
                             (switch-to-buffer initial-buffer 'norecord))))))
+          ;; Show all delayed messages in the new frame (if any).
+          (with-selected-frame (or frame (selected-frame))
+            (dolist (args (nreverse messages))
+              (apply #'message args)))

           (mapc #'funcall (nreverse commands))