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

From: "Drew Adams" <[email-masked]>
Date: Sun, 15 Jul 2012 09:43:04 -0700

>  >> Sorry.  Do (defalias 'yes-or-no-p 'y-or-n-p) and then try.
>  >
>  > Are you sure you mean that?  AFAIK, `y-or-n-p' is not at 
>  > all representative - it does not even use the minibuffer,
>  > I think: it just reads events directly.  I will try to do as
>  > you instruct, if you confirm, but I do not understand how
>  > using `y-or-n-p' here can possibly help.
> 
> Because you can do `select-frame-set-input-focus' with it.

I'm afraid I still do not understand (but maybe I don't need to).  I thought the
problem has to do with input focus for minibuffer reading.  But maybe you are
saying that the minibuffer need not be involved, and that `read-event' will also
depend on which frame has the focus.

In any case, please give me the specific recipe that you would like me to try.
I'm afraid I've lost track at this point.

And is this still pertinent, given what we have discovered wrt a reproducible
recipe from emacs -Q?

>  >> ... what command is C-] bound to?  I can't type it on my 
>  >> keyboard ...
>  >
>  > `abort-recursive-edit'.  `C-]' is the (only) default 
>  > global binding (emacs -Q) for `abort-recursive-edit'.
> 
> My keyboard doesn't allow me to input things like C-] easily 
> so I don't know what these do.

You could rebind that command to see what it does.
And `C-h f' describes it.  (It is a bit like a super C-g.)

> If you get the problem with `pop-up-frames' t and not with the special
> display settings we have simplified the problem.

Yes, greatly.

>  > A second bug (I think) is that there is NO feedback/response
>  > to your typing the answer.  With focus in the *Process List*
>  > frame, which has a read-only buffer, I would expect an error
>  > message saying that the buffer is read-only.  But you get
>  > NO message - nada.  Not only that, but I see no such 
>  > message in buffer *Messages* if I look there.  Dunno why this is.
> 
> I suppose that as long as you don't type either yes or no in the
> original frame nothing happens at all.

Presumably _some_ buffer receives the input.  If it is a read-only buffer then I
would expect a read-only error message.  If it is not then I would expect to see
what I type in some buffer.  I see neither effect.  And presumably (it seems
that way anyway) it is the *Process List* buffer, which is read-only, that has
the focus.

This behavior does not seem normal.

>  > Well, that's one problem, anyway.  Really, I do not want 
>  > the new frame popped up to have a minibuffer and pose the
>  > question about killing processes.  I want the
>  > new frame to just be displayed and _not selected_ for 
>  > input/output (user interaction).  I do not want it to have
>  > a minibuffer.
> 
> But we must select a frame for answering the question.

The frame for posing and answering all questions should be, as usual, the
minibuffer frame.  Aside from `read-event' etc., reading user input should use
the minibuffer, and that means it should use the minibuffer frame.

Looking at the C code for `yes-or-no-p' (Emacs 23.3), it clearly calls
`read-from-minibuffer' (`Fread_from_minibuffer'), so it should use the
minibuffer.  The frame that should have the input focus for that prompt and
reading should be the standalone minibuffer frame - that is the _only_ frame
that has a minibuffer.

It makes no sense for any other frame to have the input focus when reading from
the minibuffer, since no other frame _has_ a minibuffer.

>  > More precisely, I don't have much of an opinion in the 
>  > case of a non standalone minibuffer.
>  >
>  > But in the case of a standalone minibuffer, it definitely 
>  > should continue to have the input focus.  That's the point, for me.
> 
> Why "continue"?  You could invoke C-x C-c in any frame.

See above.  It should have the input focus for any _reading from the
minibuffer_.  Obviously, other frames can have the input focus when not reading
from the minibuffer.  `yes-or-no-p' reads from the minibuffer.

>  > It would not be a solution for me to give the new frame 
>  > its own minibuffer or something and to let it keep the input
>  > focus.  The user should be able to always look to the same,
>  > standalone minibuffer - the *only* minibuffer area - for all
>  > prompts and user replies.
> 
> We'll see to that.

That would be a great fix.

>  >>  > Buffer *Help* is still popped up in a new frame that has
>  >>  > those colors, but now when I hit `q' in it the frame does not
>  >>  > disappear and its buffer is changed.  That's not what I would
>  >>  > call "dedicated" anymore.
>  >>
>  >> That's hardly surprising: With `pop-up-frames' t you 
>  >> shouldn't get a dedicated window, I suppose.
>  >
>  > Uh, if you are saying what I think you are saying then I'm 
>  > afraid I disagree strongly about that.  To me, that would be
>  > a regression.
> 
> Don't be afraid.  I meant with `pop-up-frames' t and
> `special-display-buffer-names' and friends nil.

OK.

But the behavior I saw with that test indicated/suggested that *Help* was not
entirely special-display (with `pop-up-frames' t and the *Help* frame defined as
indicated with `special-display-buffer-names'.

The frame was created with the correct colors etc., but buffer *Help* ended up
being replaced in the frame, which is not what "special display" means.  So I
think there might be a second bug here.

>  > If I use Dired+ (which does what my patch does) then there 
>  > is no problem, so in my daily use this is solved for the
>  > Dired but reported, but not in general (viz.
>  > this bug wrt quitting with active processes).
> 
> But your patch doesn't address the input focus issue or am I missing
> something?

Correct.  But the problem does not exist with my patch.  I don't have an
explanation.

But please see the #15566 thread - in particular, the part about the use of code
that is nearly identical but that does not manifest the input problem.  See the
message I sent that has the attachment `throw-chmod-vs-chmod-rec.el'.  I do not
understand why what I report happens, but it happens.

This is from that thread:

>> But this is the same code sequence that occurs for `M' - 
>> AFAICT the only difference is the existence of the two
>> preliminary questions.  So it's not clear to me where the
>> problem comes from.  This is the calling sequence:
>>
>> dired-do-chmod OR diredp-do-chmod-recursive
>> dired-mark-read-string
>> dired-mark-pop-up
>> dired-pop-to-buffer
>> make-frame, then read-from-minibuffer (via FUNCTION arg)
>> 
>> The code for `dired-do-chmod' and `diredp-do-chmod-recursive' 
>> is nearly identical - see attachment.  The only difference is the 
>> gathering of the list of files (which includes the preliminary
>> confirmation questions).

But let's not worry about that here/now.  Perhaps this thread will find a
solution to the problem _in general_.  That's my current hope, at least.

>  > If you want a standalone minibuffer frame to have the 
>  > _only_ minibuffer then you must do everything at load time,
>  > i.e., in .emacs.
> 
> So this makes debugging more difficult for people who are not used to
> work with minibuffer-only frames.

Yes.  That's not my doing; it's a fact of GNU Emacs life.  Unless someone
provides a fix that changes this.

> I have attached another version of `with-temp-buffer-window' which now
> explicitly shifts input focus to the frame selected at the time the
> macro is called.  I hope this will fix the `pop-up-frames' t scenario.
> I'm afraid it will not fix the problem when you invoke C-x C-c in any
> window but the minibuffer-only window so we probably have to fix that
> issue separately.  Please try it.

Just what is the recipe to try (e.g. from emacs -Q)?

Wrt "C-x C-c in any window but the minibuffer-only window": It's about reading
from the minibuffer (e.g. `read-from-minibuffer').  It never matters (apart from
this bug about new frames that get created during the minibuffer reading) which
buffer/frame is selected when you call `read-from-minibuffer'.  Focus is always
switched to the minibuffer (and its frame).

The problem here seems to be that just after focus is correctly switched to the
minibuffer frame, for minibuffer interaction (reading), the new frame is popped
up and MS Windows gives it the focus.  At least that's the (limited) conceptual
model I'm adopting so far.

IOW, I don't think the problem is to give the minibuffer frame the focus.  I'm
assuming that that is happening correctly, as usual.  The problem, I think, is
that the new frame creation happens at the same time or just afterward, and that
steals the focus from the minibuffer frame (thanks to MS Windows).

Thx - Drew