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

From: "Drew Adams" <[email-masked]>
Date: Sun, 22 Jul 2012 09:46:51 -0700

>  >>  > 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?
> 
> Write you own version of `special-display-popup-frame' replacing
> ... with something like...
> where I used `last-event-frame' because you mentioned it.  I'm not
> familiar with that variable.

I really don't want to get into more redefining of such stuff if I can avoid it.
But we'll see.

I never heard of `last-event-frame' either until this thread, when I started
looking at this stuff more closely, trying to find something that would help.

>  >>  > 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)?
> 
> The above should be applicable to earlier versions to.

What do you mean by "the above" here?  The redefinition code you just suggested
(elided above) or something else?

>  > (redirect-frame-focus last-event-frame
>  >                       (window-frame (minibuffer-window)))
>  > Is that what you meant?
> 
> Not really because I don't understand the semantics of
> `last-event-frame' well enough.  But if it works, all the better.
> 
>  > 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?)
> 
> If you do this wrapped in a `with-selected-window' it should 
> do the same as `redirect-frame-focus'.  Otherwise, it will
> probably bring the frame into foreground.  If
> `redirect-frame-focus' works, stay with it.

Got it.  Good to know that difference.

>  > 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.
> 
> Does this happen _only_ with your code or also in the emacs 
> -Q scenarios _without_ your code?  What happens with a
> `y-or-no-p' defalias?

Not sure what you mean.  There is no equivalent in the emacs -Q tests you asked
me to do.  There is nothing on post-command-hook etc.

> Could be the abort in delete_frame I've told you about.  Why don't you
> run Emacs in the debugger jsut from the beginning?  (In a running
> instance of Emacs go to the src directory, type M-x gdb, give your
> full-path emacs.exe as argument, type "run" and do your 
> things until the emacs fired up this way becomes unresponsive.
> A "bt full" in the first instance should tell you what happened.)

I must be missing something when I try to follow that recipe.

I started Emacs with my setup.  I moved to the src directory (in Emacs 24.1,
since I don't have src for later builds - but Emacs 24.1 has the same problem).
I typed M-x gdb, appended c:/Emacs-24.1/bin/emacs.exe and hit RET.

That seemed to pop up a new emacs -Q session (splash page, none of my
customizations, minibuffer in the same frame, etc.), with this message in buffer
*Warnings*, whose window split the screen with the splash page:

"Error (initialization): User has no home directory"

(There are no messages in *Messages*.)

And in buffer *gud-emacs.exe* I see this:

(gdb) run
Starting program: /cygdrive/c/Emacs-24.1/bin/emacs.exe 
Loaded symbols for /cygdrive/c/WINDOWS/system32/ntdll.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/kernel32.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/advapi32.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/rpcrt4.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/secur32.dll
Loaded symbols for
/cygdrive/c/WINDOWS/WinSxS/X86_Microsoft.Windows.Common-Controls_6595b64144ccf1d
f_6.0.2600.6028_x-ww_61e65202/comctl32.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/msvcrt.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/gdi32.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/user32.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/shlwapi.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/comdlg32.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/shell32.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/mpr.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/ole32.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/usp10.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/winmm.dll
Loaded symbols for /cygdrive/c/WINDOWS/system32/winspool.drv

Should I have appended something different to `M-x gdb'?  This is what I use
when I start Emacs with my setup:

C:\Emacs-24.1\bin\runemacs.exe --debug-init

That is what I used this time too, before using `M-x gdb' in src/.

>  > 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.
> 
> That's a bad idea in my opinion.  Redirect as soon as possible.  Why
> don't you use `after-make-frame-functions'?

I'm not sure what you mean.  I tried this:

1. Remove the `redirect...' from `1on1-fit-minibuffer-frame'.

2. Put back the guard (eq last-event-frame (window-frame (minibuffer-window)))
at the beginning of `1on1-fit-minibuffer-frame' (so it is a no-op otherwise).

3. Defined this and added it to `after-make-frame-functions':

(defun 1on1-redirect-to-minibuffer (new-frame)
  "..."
  (when (and 1on1-fit-minibuffer-frame-flag
             (active-minibuffer-window)
             (save-selected-window
               (select-window (minibuffer-window))
               (one-window-p nil 'selected-frame)))
    (redirect-frame-focus
      new-frame
      (window-frame (minibuffer-window)))))

That did not help at all.  The original symptoms returned (typing yes/no did not
go to the minibuffer etc.).