Subject: RE: bug#11939: 24.1; `save-buffers-kill-emacs' loses minibuffer focuswhenit calls `list-processes'

From: "Drew Adams" <[email-masked]>
Date: Wed, 8 Aug 2012 09:18:46 -0700

> > What requires you to use `quit-window' and not 
> > `delete-frame'?  Just asking, to understand.
> 
> I cannot use `delete-frame' because there might be other 
> windows on the frame or because this might be the only visible frame.

But those conditions can be tested, no?

IOW, it seems to me that if we are talking about a situation where the buffer is
to be kept but its display is to be removed, there are ways of doing that.

You will no doubt find better ways to do it (e.g., at least a different test
from `one-window-p'), but FWIW I use code like the following, depending on the
context:

1.
(if (one-window-p t) (delete-frame) (delete-window))

2.
(if (and (one-window-p t)  (cdr (visible-frame-list)))
    (delete-frame) ; Sole window but not sole visible frame.
  (delete-window (selected-window)))

3.
(defun browse-kill-ring-quit-deletes-window/frame ()
  "Bury buffer.  Delete window or, if dedicated, frame.
Useful as customized value of `browse-kill-ring-quit-action'."
  (let ((buf            (current-buffer))
        (sole-window-p  (eq (selected-window) (frame-root-window))))
    (cond ((and sole-window-p (window-dedicated-p (selected-window)))
           (delete-frame)
           (bury-buffer buf))
          (t
           (unless sole-window-p (delete-window))
           ;; Avoid BUF as explicit arg to `bury-buffer',
           ;; since we want to undisplay it.
           (with-current-buffer buf (bury-buffer))))))

4.
(save-window-excursion 
  (pop-to-buffer list-buf)
  (condition-case nil ; Ignore error if user deleted window.
      (if (one-window-p) (delete-frame) (delete-window))
    (error nil))
  (if list-was-shown
      (bury-buffer list-buf)
    (kill-buffer list-buf)))

5.
(unwind-protect
     (save-window-excursion
       (dired-pop-to-buffer bufname)
       (setq result  (apply function args)))
  (save-excursion
    (condition-case nil
        (progn
          (select-window (get-buffer-window bufname 0))
          (if (one-window-p) (delete-frame) (delete-window)))
      (error nil)))
  (bury-buffer bufname))

6.
(or (fboundp 'old-delete-window)
    (fset 'old-delete-window (symbol-function 'delete-window)))

(defun delete-window (&optional window)
  "Remove WINDOW from the display.  Default is `selected-window'.
If WINDOW is the only one in its frame, then `delete-frame' too."
  (interactive)
  (save-current-buffer
    (setq window (or window (selected-window)))
    (select-window window)
    (if (one-window-p t)
        (delete-frame)
      (old-delete-window (selected-window)))))

7.
(defun delete/iconify-window (&optional window frame-p)
  "Delete or iconify WINDOW (default: `selected-window').
If WINDOW is the only one in its frame (`one-window-p'), then optional
arg FRAME-P determines the behavior regarding the frame, as follows:
  If FRAME-P is nil, then the frame is deleted (with the window).
  If FRAME-P is t, then the frame is iconified.
  If FRAME-P is a symbol naming a function, the function is applied
             to WINDOW as its only arg.
             If the result is nil, then the frame is deleted.
             If the result is non-nil, then the frame is iconified.
  If FRAME-P is anything else, then behavior is as if FRAME-P were the
             symbol `window-dedicated-p': the frame is iconified if
             WINDOW is dedicated, otherwise the frame is deleted.

Interactively, FRAME-P depends on the prefix arg, as follows:
  Without a prefix arg (prefix = nil), FRAME-P is `window-dedicated-p'.
  With prefix arg < 0, FRAME-P is t.  The frame is iconified.
  With prefix arg >= 0, FRAME-P is nil.  The frame is deleted."
  (interactive
   (list nil (if current-prefix-arg
                 (not (natnump (prefix-numeric-value
                                current-prefix-arg)))
               'window-dedicated-p)))
  (setq window (or window (selected-window)))
  (let ((one-win-p t))
    (save-window-excursion
      (select-window window)
      (if (one-window-p)
          (if frame-p
              (if (eq t frame-p)
                  (iconify-frame)
                (unless (and (symbolp frame-p)
                             (fboundp frame-p))
                  (setq frame-p 'window-dedicated-p))
                (if (funcall frame-p window)
                    (iconify-frame)
                  (delete-frame)))
            (delete-frame))    ; Default.
        (setq one-win-p nil)))
    ;; Do this outside `save-window-excursion'.
    (unless one-win-p (old-delete-window window))))

8.
(defun delete-1-window-frames-on (buffer)
  "Delete all visible 1-window frames showing BUFFER."
  (interactive
   (list (read-buffer 
          "Delete visible 1-window frames showing buffer: "
          (current-buffer) 'EXISTING)))
  (setq buffer  (get-buffer buffer))
  (save-excursion
    (when (buffer-live-p buffer)        ; Do nothing if dead buffer.
      ;; Better to search frames or `get-buffer-window-list'?
      (dolist (fr  (filtered-frame-list 
                    `(lambda (fr) (get-buffer-window ',buffer))))
        (save-window-excursion
          (select-frame fr)
          (when (one-window-p t fr) (delete-frame)))))))