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

From: "Drew Adams" <[email-masked]>
Date: Wed, 1 Aug 2012 09:34:50 -0700

> What does M-n do?

M-n is standard Emacs in the minibuffer: it retrieves (inserts) the default
value provided to the minibuffer-reading function (e.g. `completing-read').
(And starting with Emacs 23 you can repeat M-n to cycle among multiple default
values.)

>  > 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.

It inserts the default value.  In this case, the default value is the value of
(current-buffer), as I explained.  The problem/mistake is that with the
`add-hook' the value of (current-buffer) is now buffer " *Minibuf-0*".

>  > 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*.

Yes.  (current-buffer) should not be *Minibuf-0*.  (But (current-buffer) is only
the default value, so I can still use `C-x k' here, by ignoring the default.)

>  > 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.

That is what I understood. 

>  > 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

Correct.  Same scenario, still.

>  > 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.

Right (but M-:, not C-:).

>  > 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.

OK.  I, even less, obviously.

But at any rate, this wrong-buffer problem is minor.  I don't want it to
sidetrack us too much.

The bigger issue is to have code somehow DTRT so that minibuffer interaction
that is coupled with the popup of an informational-only window/frame, keeps the
focus in the minibuffer frame.  IOW, come up with some construct that lets code
identify a particular minibuffer interaction as one that should keep the focus
in the minibuffer frame.  

"Keep" here might mean redirect to the minibuffer if something outside Emacs and
outside the user moves the focus away from it.  And that "outside Emacs and
outside the user" would be key, if we could in fact detect it.  IOW, Emacs code
can only say that some interaction should keep the focus in the minibuffer frame
(or not, depending on what's intended).  Emacs cannot prevent MS Windows or
whatever from changing the focus.  And we would want the user to be able to
change the focus explicitly (during the minibuffer interaction), of course.

>  > The above behavior description holds for all Emacs versions I have.
>  > The `add-hook' solves the unfocused minibuffer frame problem 
>  > for all versions.

Again, I was wrong about that (e.g. *Backtrace* case).  There are some cases
where the minibuffer is active and a frame is popped that is not merely
informational but should in fact receive the input focus.

>  > 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.

Of course.  I meant only that perhaps the equivalent of what I did in the hook
might be something to do in general.  I'm now backtracking on that because doing
that systematically is not the panacea that I thought it might be.

>  > 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.

The answer is no, because I said "systematically", and that is not TRT (e.g.
*Backtrace*).