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

From: "Drew Adams" <[email-masked]>
Date: Sat, 21 Jul 2012 11:13:10 -0700

> Are you sure you started Emacs again before you went through
> (progn
>    (setq pop-up-frames t)
>    (load "~/with-temp-buffer-window.el")
>    (shell))
> 
> Here I get a new frame in the foreground, focussed, with the process
> list in its root window and the `yes-or-no-p' prompt in its minibuffer
> window.  Please try once more.  If this does not work on your 
> system, we might have a smoking gun.

My bad, I think.  I think what I did was forget to load your code (!).  I tried
again, using emacs -Q with the following, and it did what you say (i.e., no
problem):

(progn
  (load-file "~/drews-lisp-20/contrib/cygwin-mount.el")
  (load-file "~/drews-lisp-20/setup-cygwin.el")

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

>  >> You did not report whether it works for 
> `minibuffer-auto-raise' nil.
>  >> Can you look into that?
>  >
>  > It is nil by default, no?  So the tests for #2 test that.
> 
> It's a NOOP for #2.

I tried also with the above code, inserting (setq minibuffer-auto-raise nil)
after (shell).  No problem, and no difference from not having that code.

>  > the best behavior (if possible) would be to have the 
>  > question appear in the minibuffer of the *Process List*
>  > frame (and have that frame be foremost).
> 
> That's what happens here in scenario #2.

Same here.

>  > Got it.  I don't get a crash (on MS Windows).  Are you 
>  > seeing the crash on MS Windows also?
> 
> On Windows.

Hm.

>  > I imagine that your code is applicable only to Emacs 24+
>  > (is that right?), so it could not have
>  > helped fix things with my setup for other Emacs versions.
> 
> Yes.  But maybe you could adapt your buffer display function
> accordingly.

What do you mean?

>  > What about other Emacs releases - are relevant at 
>  > all in this context?
>  > Should we expect that your code can help them also?
> 
> If you have an appropriate hook.

Meaning?  Is this something I can do (how)?

>  >> Try explicitly redirecting the focus from the new frame to the
>  >> minibuffer-only frame via `redirect-frame-focus'.
>  >
>  > Where?  At the end of `1on1-fit-minibuffer-frame', instead of
>  > `select-frame-set-input-focus'?
> 
> I think so.
> 
>  > And would this be in order to try to make things work even 
>  > without your code (e.g., for older Emacs versions)?  Because if
>  > not I do not need to do it, since the code I have now already
>  > works well in Emacs 24, when I use your code also.
>  >
>  > IOW, I'm not clear what you are suggesting, and what 
>  > problem it might solve.  If it is a possible cure for the problem
>  > in other Emacs versions, e.g. without your code, then I'll
>  > definitely try it.
> 
> If your `1on1-fit-minibuffer-frame' can hook in after the new 
> frame pops up, it might be worth a try.  With
> `temp-output-buffer-show' the only suitable hook at your
> disposition is `temp-buffer-show-hook' where selecting another
> window won't work because the hook's call is wrapped in
> `with-selected-window'.  But you can remember the new 
> frame's window and select it later, for example, in
> `post-command-hook'.

I don't understand everything you said, but that's OK - I can refer back to it
later if I need to try to understand more.

I tried adding this at the end of `1on1-fit-minibuffer-frame',
instead of guarding the function with the test
(eq last-event-frame (window-frame (minibuffer-window))):

(redirect-frame-focus last-event-frame
                      (window-frame (minibuffer-window)))

Is that what you meant?

That works, in all Emacs versions, even without your code!  And so does using
this in its place:

(select-frame-set-input-focus
  (window-frame (minibuffer-window)))

(Is there a difference?  What is the advantage of either?)

But there is a problem, for Emacs 23+.  It happens in my setup, with the call to
`redirect-frame-focus' added at the end of `1on1-fit-minibuffer-frame'.  I can
also repro it with a reduced version of my setup - essentially loading
oneonone.el and fit-frame.el and doing (add-hook 'post-command-hook
'1on1-fit-minibuffer-frame) so that I pick up the redirection that is needed.

[BTW, for oneonone.el users who do not use fit-frame.el I suppose I will put the
redirection directly on `post-command-hook', instead of putting it at the end of
`1on1-fit-minibuffer-frame'.  I will no doubt have to use a similar guard: do
nothing unless (a) the minibuffer window is active, (b) the minibuffer frame is
`last-event-frame', and (c) the minibuffer window is alone in its frame.]

Anyway, this the problem:

1. When I do C-x C-c, and respond to the yes/no question, it seems I must wait a
tiny bit before typing yes/no.  Otherwise, the first char (e.g. `y') is lost, so
I end up with just `es' (I see the `y' nowhere).  Not a big deal; just FYI.

2. If I type "no," and then I do `C-x k', then even though *Process List* has
its frame border highlighted as if it is selected, the buffer proposed for
deletion is *shell*.  OK, so I kill *shell*, and confirm ("yes') to kill its
processes also.  (BTW, `C-x k' in my setup also deletes the window/frame.)  So
far, so good.

But if I try to use `C-x k' again to kill *Process List*, then, as soon as I hit
the `k':

a. The default buffer to kill is proposed as some other buffer, not *Process
List* (in my setup the default value is automatically inserted in the
minibuffer, so I can see it without doing M-n).

b. Emacs crashes, but gives no "fatal error" dialog box - hence no way to access
gdb.  It just directly shows the MS Windows dialog box for sending an error
report to MS.  When I click yes/no in that dialog box Emacs exits (disappears).

I can repro this systematically, but there seems to be no way to use gdb.  If I
do something else instead of `C-x k' - e.g. `C-x o', then there is no problem.
I can, for instance, use `C-x o' to move among frames (`C-x o' moves to the
other frame in my setup, if there is no other window on the same frame), coming
eventually to *Process List*, and then use `C-x k' to kill *Process List*.

This crash is reproducible also with Emacs 23.3, not just with the latest Emacs
24 build.  It does not happen with Emacs 22.3, however.  Dunno whether this
crash is related to the crashes you are seeing.

Anyway, it seems we are very close, for my needs.  I suppose I can put that
redirection on `post-command-hook' (instead of in `1on1-fit-minibuffer-frame',
which some oneonone.el users will not use), and things should generally work.  I
will try that next.

Another problem I saw, when I used only a reduced version of my setup, was that
(presumably because of the redirection?) `query-replace' no longer worked: When
I hit `y' or `.' to replace, no replacement occurred.  I will try later to repro
this etc.

I want to get this info off to you now so you can digest it.

Thx - Drew