Subject: bug#11939: 24.1; `save-buffers-kill-emacs' loses minibuffer focus when it calls `list-processes'

From: martin rudalics <[email-masked]>
Date: Wed, 18 Jul 2012 18:16:11 +0200

> 1. Used my setup.  Then did the defalias.  Then loaded your file.  Then `M-x
 > shell'.  Then `C-x C-c'.  Then `y'.  No problem.

See below.

 > BTW, you did not answer my question of how you get shell etc. to work on Windows
 > with emacs -Q and without Cygwin.  I'm still interested to learn what you are
 > doing in that regard.

I'm using cmd.exe.

 >> I suppose that we should (at least optionally) have all functions
 >> accessing the minibuffer redirect frame focus to it first.
 >
 > I thought that was already the case - it seems to be.  In the problem reported
 > for this bug the minibuffer frame had the focus, but it then lost it because of
 > a frame switch (I mean, because a new frame creation by Windows switched the
 > focus).

As a matter of fact `yes-or-no-p' indirectly calls read_minibuf which does

   if (!EQ (mini_frame, selected_frame))
     Fredirect_frame_focus (selected_frame, mini_frame);

So focus is redirected but somehow this doesn't always work when popping
up a new frame.  In any case, it's not necessary to do the defaliasing,
`yes-or-no-p' should do the same, in principle.  Moreover, my
`redirect-frame-focus' call in `y-or-n-p' was silly because I mixed up
the arguments.  So let's forget about this.

I still don't understand the consequences described in the doc-string of
`redirect-frame-focus' as

    A frame's focus redirection can be changed by `select-frame'.  If frame
    FOO is selected, and then a different frame BAR is selected, any
    frames redirecting their focus to FOO are shifted to redirect their
    focus to BAR.  This allows focus redirection to work properly when the
    user switches from one frame to another using `select-window'.

    This means that a frame whose focus is redirected to itself is treated
    differently from a frame whose focus is redirected to nil; the former
    is affected by `select-frame', while the latter is not.

so there might be still some surprises around the corner.

IMHO the thing that's crucial is that if you want to peruse a separate
minibuffer frame after popping up a new frame, you have to do it from
the freshly popped up frame.  For example, if you pop up a new frame and
then want to ask a `yes-or-no-p' question, you have to select the new
frame, issue the `yes-or-no-p' there, and hope that read_minibuf
correctly redirects the prompt to the minibuffer frame.  If
`minibuffer-auto-raise' is non-nil, this will raise the minibuffer
frame, otherwise it will only redirect input to that frame.  I suppose
that was already your understanding of this issue but I was surprised
that issuing the `yes-or-no-p' from an old frame won't work.

So I attach yet another version of `with-temp-buffer-window'.  Please
test it with

(progn
   (load "~/with-temp-buffer-window.el")
   (shell)
   (setq minibuffer-auto-raise t) ; Optional
   (setq pop-up-frame-function (lambda () (make-frame '((minibuffer . nil)))))
   (setq pop-up-frames t))

(progn
   (setq pop-up-frames t)
   (load "~/with-temp-buffer-window.el")
   (shell))

and with your usual settings and tell me what you see.  Also test it
with `minibuffer-auto-raise' either nil or t.  Finally, try to exit it
in various ways, for example by deleting some frame during the dialogue.
I found a not yet 100% reproducible way to crash Emacs doing that.

If the above work, test also the delete files in dired scenario.  The
first dialogue will probably fail in the usual way, then you have to
load `with-temp-buffer-window.el' once more and try another time.

Thanks, martin