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

From: martin rudalics <[email-masked]>
Date: Mon, 30 Jul 2012 11:13:21 +0200

> Here's the (current) issue and scenario.  It uses my setup (with untweaked
 > oneonone.el but also with the other libraries that I use).  The only thing I've
 > done differently than usual is to evaluate this sexp:
 >
 > (add-hook 'after-make-frame-functions
 >           (lambda (frame)
 >             (redirect-frame-focus frame
 >              (window-frame (minibuffer-window)))))
 >
 > I do M-x shell.
 > Then I do C-x C-c.
 >
 > The `yes-or-no-p' prompt about active processes appears in the minibuffer.  I
 > type "no" into the minibuffer.
 >
 > So far so good.  Things are perfectly normal now, and I am at top level (the
 > minibuffer has exited normally).
 >
 > I then do C-x k.
 >
 > Because my setup automatically inserts the default value (what `M-n' gives),

What does M-n do?

 > that buffer-name value is inserted in the minibuffer, waiting for me to hit RET
 > to accept it or to edit it and then hit RET.
 >
 > The default buffer name in this case is " *Minibuf-0*".  That is what I have
 > never seen before.  I.e., without adding that `add-hook' sexp (above), I do not
 > get this behavior.

I understand.  Then we have to look at the command M-n is bound to.

 > But I am not in any way trapped in the minibuffer.  I can edit the buffer name
 > to kill the buffer I want.  Or I can hit C-g.  And so on.

But, apparently, whatever you do, the current buffer is still *Minibuf-0*.

 > The only problem is that the value of `(current-buffer)' is " *Minibuf-0*" at
 > that point.  I know that by testing with `message' etc.  That is why I
 > hypothesized that something in that frame focus redirection caused the buffer "
 > *Minibuf-0*" to become selected, i.e., the `current-buffer'.
 >
 > But you corrected me, pointing out that `yes-or-no-p' does that: it selects the
 > minibuffer window/buffer.

Let me try to correct this again: `yes-or-no-p' selects the minibuffer
window.  `redirect-frame-focus' does not select any window.  I don't
know how this is related to your problem.

 > If I do not do the `add-hook', then I cannot type yes/no to the `yes-or-no-p'
 > prompt, without first manually selecting the minibuffer frame (e.g. by clicking
 > its titlebar).  And if I do that then the symptoms are the same as when I use
 > the `add-hook': after typing "no", if I use C-x k then " *Minibuf-0*" is the
 > default buffer to kill.

... where C-x k is not bound to `kill-buffer' but to another function ...

 > But if (I do not do the `add-hook' and) I do `M-: (yes-or-no-p "Foo? ")' and I
 > answer "no", then `C-x k' uses another buffer (the one selected before the M-:)
 > as the default value.  I am not sure why this difference, i.e., why
 > `yes-or-no-p' does not leave " *Minibuf-0*" as the current buffer in this case.
 > But it probably has to do with the execution of command `M-:' - IOW, in that
 > test it is not just `yes-or-no-p' that is involved, but also `M-:'.

`eval-expression' does consider the minibuffer window selected when it's
called from within the minibuffer.  Doing

C-h f

and then

C-: (selected-window) RET

will print the minibuffer window.

 > So perhaps this is only a problem with (because of) `yes-or-no-p'.  And perhaps
 > there is nothing that can (or should?) be done about it.  It is anyway a minor
 > problem compared to the general problem that this bug report is about: loss of
 > focus to the minibuffer frame.
 >
 > I hope we are now clear about this `C-x k' default-buffer problem.  Dunno what
 > can or should be done about it.  It seems (to me, so far) to be a problem with
 > `yes-or-no-p' (and perhaps some other functions?):
 >
 > In order to ask its question, `yes-or-no-p' not only redirects input focus to
 > the minibuffer but it also (apparently) selects the minibuffer's buffer.  And it
 > apparently leaves that buffer selected, as the `current-buffer'.
 >
 > You know better than I what, if anything could/should be done to correct this.
 > Should `yes-or-no-p' use `with-current-buffer' or something, so that it finishes
 > by selecting again the buffer that was selected when it started?  I'm guessing
 > yes, but I know nothing about the code.  It seems wrong that it should change
 > the selected buffer to the minibuffer and leave it so changed.

The code that does the selection and the restoration is in read_minibuf
which `yes-or-no-p' calls.  As explained earlier, I don't understand
that code well enough in order to tell what to change.

 > The above behavior description holds for all Emacs versions I have.  The
 > `add-hook' solves the unfocused minibuffer frame problem for all versions.
 >
 > That means also that for Emacs 24 I do not need to use the
 > `with-temp-buffer-window.el' code you sent.  It is sufficient to use the
 > `add-hook'.  Dunno whether that helps you decide something for Emacs 24.

The code has to work without any additional setup.

 > Given the info above, do you think that the equivalent of that `add-hook' should
 > perhaps be built into Emacs?  IOW, is some code correction in order, to do
 > systematically what the `add-hook' workaround accomplishes?

I don't know, unfortunately.

martin