Subject: bug#11939: 24.1; `save-buffers-kill-emacs'losesminibufferfocuswhenitcalls`list-processes'

From: "Drew Adams" <[email-masked]>
Date: Sat, 25 Aug 2012 21:11:51 -0700

FYI -

I had updated my version of `special-display-popup-frame' to fit the latest
Emacs 24 definition of it.  (All my version tries to do differently is fit the
popped up frame to its buffer, nothing more.)

It turns out that in making that update I dropped this sexp from my original
definition of the function - the sexp is not in the vanilla Emacs definition:

  (set-window-buffer window buffer)

I have now added that back, because the code does not work without it.  The
problem was that the frame popped up did not show the BUFFER.  It showed another
buffer.

I mention this in case it might also be needed for the vanilla code (?), or in
case it might point to a bug somewhere.  You understand these things better than
I, Martin.  Perhaps you will understand just what is going on.

Below is the full definition I am using, which works fine now, (just as before
Emacs 24).  You don't care about the code that fits the frame, but I show the
full definition, just in case it helps you understand better why I might need to
explicitly `set-window-buffer' and the vanilla code apparently does not need to
do that (?).

If you learn something from this, or if you can tell me what I'm not
understanding, please let me know.  Thx.

(defun special-display-popup-frame (buffer &optional args)
  "Pop up a frame displaying BUFFER.  Return its window.
If BUFFER is already displayed in a visible or iconified frame then
raise that frame.  Otherwise, display BUFFER in a new frame.

Optional argument ARGS is a list specifying additional information.

If ARGS is an alist, use it as a list of frame parameters.  If these
parameters contain (same-window . t) then display BUFFER in the
selected window.  If they contain (same-frame . t) then display BUFFER
in a window of the selected frame.

If ARGS is a list whose car is a symbol then use (car ARGS) as a
function to do the work: display the buffer and raise its frame.  Pass
it BUFFER as first argument, and (cdr ARGS) as the rest of the
arguments."
  (if (and args (symbolp (car args)))
      (apply (car args) buffer (cdr args))
    (let ((window  (get-buffer-window buffer 0)))
      (or
       ;; If we have a window already, make it visible.
       (and window
            (let ((frame  (window-frame window)))
              (make-frame-visible frame)
              (raise-frame frame)
              (when (fboundp 'display-buffer-record-window) ; Emacs 24+
                (display-buffer-record-window 'reuse window buffer))
              (when (fboundp 'fit-frame) (fit-frame frame))
              window))                  ; Return the window.
       ;; Reuse the selected window if the caller requested it.
       (and (cdr (assq 'same-window args))
            (condition-case nil ; Try Emacs 24 `switch-to-buffer' first.
                (progn (switch-to-buffer buffer nil t) (selected-window))
              (error            ; Try again, with old `switch-to-buffer'.
               (condition-case nil
                   (progn (switch-to-buffer buffer) (selected-window))
                 (error nil)))))
       ;; Stay on the same frame if requested.
       (and (or (cdr (assq 'same-frame args))  (cdr (assq 'same-window args)))
            (let ((pop-up-windows                t)
                  (pop-up-frames                 nil)
                  (special-display-buffer-names  ())
                  (special-display-regexps       ()))
              (display-buffer buffer)))
       ;; If no window yet, make one in a new frame.
       ;; `make-frame' creates the frame before the buffer is shown in it,
       ;; so do not call `fit-frame' until we can select the buffer's window.
       (let* ((make-frame-functions
               (delq 'fit-frame after-make-frame-functions))
              (frame
               (with-current-buffer buffer
                 (make-frame (append args special-display-frame-alist))))
              (window (frame-selected-window frame)))

         ;; *** IS THIS NOT NEEDED ALSO FOR VANILLA EMACS?  WHY NOT? ***
         (set-window-buffer window buffer)

         (set-window-dedicated-p window t)
         (when (fboundp 'display-buffer-record-window) ; Emacs 24+
           (display-buffer-record-window 'frame window buffer))
         ;; Now call `fit-frame', with WINDOW selected.
         (with-selected-window window (fit-frame))
         window)))))   ; Return the window.