all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: "Drew Adams" <drew.adams@oracle.com>
To: "'martin rudalics'" <rudalics@gmx.at>,
	"'Stefan Monnier'" <monnier@iro.umontreal.ca>
Cc: 'Tassilo Horn' <tassilo@member.fsf.org>, emacs-devel@gnu.org
Subject: undisplay temporary dialog buffers when done [was: ... dedicated windows and popup frames]
Date: Sun, 10 Jul 2011 16:45:26 -0700	[thread overview]
Message-ID: <1C868A007F33466FA852C4589C08B139@us.oracle.com> (raw)
In-Reply-To: <D2372B52AC294892B7D1E4E89FC083D9@us.oracle.com>

For code that temporarily displays a buffer for the duration of a user-input
dialog, I suggested that we might wrap that code, so that when the dialog is
finished the buffer's display disappears: it is undisplayed as part of unwinding
the dialog.

This pertains to buffer displays such as *Completions* and the Dired
marked-files list (e.g. when you delete, copy, etc. files).  Such buffers are
popped up in a window that might be dedicated, in a separate frame, etc.,
depending on user settings.  We generally want to get rid of the buffer's
display in such cases.

This was the suggestion:

> Perhaps we could add a way for code to indicate that it is 
> displaying a given buffer only for the purpose and duration
> of a user dialog, and thus:
> 
> a. For that duration the buffer's frame (if separate) would 
>    have its input focus redirected to the minibuffer's frame.
> b. After the dialog finishes, the buffer's frame (if 
>    separate) would be deleted.
> 
> E.g., something like: (with-dialog-buffer BUF ...)
> Perhaps something like that could be a way to handle the 
> general case (providing that coders actually used it).

This approach gives the code that carries out the user-input dialog and displays
the supporting information buffer the responsibility and possibility of making
that buffer disappear when the dialog is over.  IOW, it keeps control over such
behavior local to where it is needed.

Here is an example of what I meant by such a macro (not tested much).  Instead
of `with-dialog-buffer' I named it `undisplay-on-unwind'.  It need not be
associated with dialog code, but that is probably the typical case.

(defmacro undisplay-on-unwind (buffer &rest body)
  "Undisplay BUFFER after evaluating BODY.
If BUFFER is not shown in the selected window or
`minibuffer-selected-window', then bury BUFFER (`bury-buffer') and
delete all windows showing it, if possible.
Use this in particular when BODY pops up BUFFER as part of a temporary
dialog and there is no need to show BUFFER after the dialog is
finished."
  (let ((buf  (make-symbol "buf")))
    `(unwind-protect
          (progn ,@body)
       (let ((,buf  ,buffer))
         (when (bufferp ,buf) (setq ,buf  (buffer-name ,buf)))
         (when (stringp ,buf)
           (let ((swin  (selected-window)))
             ;; Do nothing if BUFFER is in the selected window
             ;; or the minibuffer window is selected now
             ;;    and BUFFER's window was selected just before.
             (when (window-minibuffer-p swin)
               (setq swin  (minibuffer-selected-window)))
             (when (and (get-buffer-window ,buf 'visible)
                        (window-live-p swin) ; Needed?
                        (not (eq (window-buffer swin)
                                 (get-buffer ,buf))))
               ;; Ignore, in particular, "Attempt to delete
               ;; the sole visible or iconified frame".
               (ignore-errors (delete-windows-on ,buf))
               (bury-buffer (get-buffer ,buf)))))))))

This is adapted from part of how I treat `*Completions*' in Icicles.  The point
here is to give an idea of what such a macro might be - I don't argue that this
particular implementation is necessarily correct, complete, what we want, etc.

The idea is to couple (a) the display of a buffer whose only purpose is to
provide info for some input dialog with (b) that dialog.  The BODY for the macro
would typically be code that displays BUFFER and asks for some user input.
After that dialog is finished, we remove all display of BUFFER.

You can try it a bit.  E.g.:

(defun bar (f1 &optional f2)
  (let ((foo  (get-buffer-create "*FOO*")))
    (with-current-buffer foo
      (erase-buffer)(insert "HHHHHHHHHHHHHHHHHHHHHHHHHHHH"))
    (funcall f1 foo)
    (when f2
      (save-selected-window
        (select-window (get-buffer-window "*FOO*" 'visible))
        (funcall f2 foo))))
  (redisplay t)(sleep-for 3))

;; 1. Show *FOO* in a separate window (by default).
(undisplay-on-unwind "*FOO*" (bar 'display-buffer))

;; 2. Like previous, but with *FOO* in a separate frame.
(undisplay-on-unwind "*FOO*" (bar 'display-buffer-other-frame))

Those two represent the typical case, but we can imagine that `*FOO*' might be
displayed in more than one window.

;; 3. Like previous, but two *FOO*s, one in a separate frame.
(undisplay-on-unwind "*FOO*" (bar 'display-buffer
                                  'display-buffer-other-frame))

;; 4. Like previous, but won't delete the frame
;;    from `make-frame-command'.
(undisplay-on-unwind "*FOO*" (bar 'display-buffer
                                  '(lambda (f)
                                    (make-frame-command))))




  parent reply	other threads:[~2011-07-10 23:45 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-07-08 14:19 Usage examples of dedicated windows and popup frames? Tassilo Horn
2011-07-08 14:47 ` Richard Riley
2011-07-08 14:49 ` John Yates
2011-07-08 16:11 ` Stefan Monnier
2011-07-08 16:34   ` Drew Adams
2011-07-08 16:51     ` Stefan Monnier
2011-07-08 17:38       ` Drew Adams
2011-07-08 17:54   ` Tassilo Horn
2011-07-08 18:55     ` Stefan Monnier
2011-07-09 13:00       ` martin rudalics
2011-07-09 15:03         ` Drew Adams
2011-07-10  0:43           ` chad
2011-07-10  9:00             ` martin rudalics
2011-07-10  9:43             ` Drew Adams
2011-07-12 17:47               ` chad
2011-07-12 18:55                 ` Drew Adams
2011-07-13  6:24                 ` martin rudalics
2011-07-13 23:09                   ` chad
2011-07-10 23:45           ` Drew Adams [this message]
2011-07-09 17:22         ` Tassilo Horn
2011-07-10  9:00           ` martin rudalics
2011-07-10  9:39             ` Tassilo Horn
2011-07-10 15:30               ` martin rudalics
2011-07-10 16:00                 ` Tassilo Horn
2011-07-10 21:13                   ` Drew Adams
2011-07-08 16:11 ` Drew Adams

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1C868A007F33466FA852C4589C08B139@us.oracle.com \
    --to=drew.adams@oracle.com \
    --cc=emacs-devel@gnu.org \
    --cc=monnier@iro.umontreal.ca \
    --cc=rudalics@gmx.at \
    --cc=tassilo@member.fsf.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.