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

Previous Next

Package: emacs;

Reported by: "Drew Adams" <drew.adams <at> oracle.com>

Date: Fri, 13 Jul 2012 18:07:01 UTC

Severity: normal

Found in version 24.1

Done: martin rudalics <rudalics <at> gmx.at>

Bug is archived. No further changes may be made.

Full log


Message #296 received at 11939 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Drew Adams <drew.adams <at> oracle.com>
Cc: 11939 <at> debbugs.gnu.org
Subject: Re: bug#11939: 24.1;
	`save-buffers-kill-emacs' loses minibuffer focuswhenit
	calls	`list-processes'
Date: Sat, 04 Aug 2012 15:44:53 +0200
> It is only the code that is calling for such a user dialog that knows that that
> is what is being called for.  By "such a user dialog", again, I mean (a) the
> display of a buffer for information only, i.e., one that does not need the input
> focus, and (b) request of user input with the previous buffer remaining current
> and the minibuffer having the input focus.
>
> That is the use case that is problematic.  It is the case where the above
> systematic "fix" is inappropriate.  There might be other such use cases, but it
> is the only one I have encountered.  And I have encountered it in several
> different places (e.g., Dired *Marked Files* popup, *Process List* popup).
>
> My suggestion is, again, that we try to come up with a construct that covers
> this use case, and then use it in the appropriate places: places where we do (a)
> + (b).

Users who want to pop up a frame with a minibuffer almost certainly want
to supply their input right in the frame where the informational buffer
is displayed.  So there is a use case where the informational buffer
must be made current.  Also, when the new frame is popped up and
`handle-switch-frame' switches to it, the informational buffer is made
current anyway.  So we'll have a hard time preserving the "with the
previous buffer remaining current" requirement throughout the dialog.

> On the other hand, if you know of a way to _detect_ such an intention on the
> part of the developer, i.e., somehow _detect_ whether the displayed buffer
> should have input focus, then I'm all ears.

You know that buffers don't have input focus - only frames do, so please
keep this distinction alive here.  I think we agree that developers
leave it to us users to decide whether the buffer is shown in a new or
an existing frame.  For a use case where the frame of the displayed
buffer should have input focus see the `pop-up-frames' non-nil case.

> I don't expect that to be possible, which is why I propose that the developer
> make the intention explicit by using a new construct (e.g. a macro) that takes
> care of this.
>
> The construct would display the informational buffer and redirect its input
> focus to a standalone minibuffer, if there is one.  If there is no standalone
> minibuffer frame, then that part could be a no-op, AFAICT.

We would at least have to make this optional.  Users might want to
prefer standalone buffers for most of their input but prefer answering
the dialogs we talk about here in a minibuffer frame with the list of
files being displayed in the same frame.  The new option, let's call it
`always-redirect-input-to-standalone-minibuffer-frame', if non-nil,
could be used by your construct.

> Something like this:
>
> (with-unfocused-buffer-displayed BUFFER &body BODY)
>
> where BUFFER is displayed for information only, and where BODY would include the
> call(s) that read from the minibuffer.
>
> The current buffer would remain what it was beforehand, and _if_ BUFFER gets
> displayed in its own frame and _if_ there is a standalone minibuffer frame,
> _then_ the focus for BUFFER's frame gets automatically redirected to the
> minibuffer frame.

In my experience, this requirement is met if the construct requests
input with BUFFER's window temporarily selected and BUFFER temporarily
current.  Or am I missing something?

> If those conditions do not hold then there is no special
> handling needed - the construct can essentially be a no-op in that case
> (AFAICT).
>
> How something like this would be implemented I'm not sure.  When the redirection
> would need to take place, to DTRT, I'm not sure.  Perhaps it would need to be
> done more than once.
>
> But an important further requirement is that nothing should prevent Emacs code
> in BODY or called from within BODY from switching the input focus to BUFFER's
> frame.

I don't understand what BODY should contain.  Would this macro be
responsible for displaying BUFFER?

> Likewise, nothing should prevent the user from explicitly switching the
> focus to BUFFER's frame.

This is part of the `yes-or-no-p' dialog, nothing within the scope of
the construct you propose.

> The only switching of focus to BUFFER's frame that this construct would be
> trying to prevent would be something that comes from neither a user action nor
> the Emacs code - in particular, MS Windows auto-focussing a newly created frame.

And the only way of "trying to prevent" I can think of is to redirect
focus by requesting input from BUFFER's frame.

> Again, I don't know the "how".  But (so far) I'm convinced that this has to be
> an explicit Emacs construct: there needs to be some way for a Lisp programmer to
> communicate the intention that BUFFER is not intended to have the input focus

... BUFFER's frame ...

> during BODY (unless that is done by the user or by code within BODY).

... during the subsequent reading from the minibuffer.  BODY has
terminated long ago at that time I suppose.

> I do not expect that the problematic use case we've been discussing can be
> detected and dealt with correctly in an automatic way.  If the programmer
> intention

Who is the programmer here?

> cannot be made explicit then there is no way to know what TRT is.

First we have to separate application from user in a clear way.

> It's problematic enough even with the intention communicated, in the sense that
> we need to allow users and Emacs code to give focus to BUFFER's frame if they
> want to.  IOW, even if we _know_ that initially BUFFER's frame should not be
> focused, it is hard enough to prevent or undo focusing by MS Windows while still
> allowing users and Emacs to focus BUFFER.

Yes.

> That's the point of providing programmers with a construct to express that
> intention explicitly: "This buffer's frame, if it is displayed in its own frame,
> should not receive the focus."

Let's be realistic, programmers won't care.  We can only provide a
construct that's convenient enough and has been tested in a few model
cases like the ones we know of.

> By "might pop up" I meant that _if_ informational BUFFER is popped up in its own

minibuffer-less

> frame, _then_ the intention is that that frame not receive the input focus.
>
>>  > redirecting focus for any new frames to the minibuffer.
>>
>> And what you have in mind here should be distinguishable from other
>> things that pop up frames but do not want the redirection.
>
> Not sure I follow you.  Are you referring to the equivalent of possibly nested
> `with-unfocused-buffer-displayed' calls?

I refer to the case where a minibuffer-equipped frame is popped up.

> Here's the thing.  I don't know whether we can come up with something that is
> 100% reliable.  But the important thing, I think, is to have _some_ programmatic
> translation of the programmer intention that this BUFFER be shown without giving
> it the input focus.
>
> Today there is no way for a programmer to indicate that.  S?he might not
> _expect_ that the focus would be grabbed away from a minibuffer frame and given
> to a new frame, but that lack of expectation today is mainly based on
> inexperience with a standalone minibuffer and MS Windows.
>
> What's needed is some way to reinforce the programmer's natural expectation that
> the user can in fact type input into the minibuffer even when the informational
> buffer gets displayed.
>
> No one would naturally expect that not to be the case, but it can be the case,
> unfortunately.  So the idea is to somehow support the natural expectation and
> take away the possibility (or reduce the probability) of MS Windows interfering
> with what should be a simple user dialog.

OK.  If you think that the way with-temp-buffer-window.el handles it is
not enough, tell me what you would do instead.

>> What you want is some clairvoyance in step (1) of my description
>> above whether step (2) will be performed.
>
> No, I don't think so.  I don't believe in such clairvoyance (but I'm open to
> being convinced).  Instead, I believe in the programmer stating that the buffer
> is not intended to have the focus.  (But that nothing should prevent Emacs or
> the user from giving it the focus at some point.)

Why don't you code the macro you have in mind so we can discuss it?

>> `with-temp-buffer-window' avoids that by asking the `yes-or-no-p'
>> question in the new frame.
>
> The issue at stake is the case of a standalone minibuffer.  I don't see any
> problem if there is no standalone minibuffer frame.
>
> With a standalone minibuffer frame, the proper behavior is for the minibuffer
> frame to be used for all minibuffer activity.  Anything else is less than
> desirable, even if it might be acceptable if no better solution could be found
> in some case.
>
> A user of a standalone minibuffer looks there for all echo-area output and all
> minibuffer input.  That is one of the reasons for using a standalone minibuffer:
> a single place where all Q & A with the user takes place.
>
> Well, nearly all.  Yes, there are some times where things like `read-event' are
> used instead of the minibuffer.  But let's not get pedantic; this is about use
> of the minibuffer and echo area.  A standalone minibuffer offers the advantage
> of always looking to the same place on the screen for user I/O.

So let's use an option like
`always-redirect-input-to-standalone-minibuffer-frame' and you propose a
macro that does what you mean based on that option (I'm afraid I do not
understand well what you think that macro's BODY should do).

> The other potential trouble is the need to show an informational buffer that
> does not necessarily correspond to what you have defined for
> `with-temp-buffer-window'.

So you think it's too restrictive?

> To be clear, I do not know whether such a need exists much in practice.  But it
> looks to me like your macro and the related code you sent make additional
> assumptions about the buffer that is popped up that constrain it more than what
> I was describing abstractly for the hypothetical
> `with-unfocused-buffer-displayed'.

It's a substitute for `with-output-to-temp-buffer' with an additional
function that can be used to replace the return value of the former.

> The buffer in the case of `with-temp-buffer-window' starts out from scratch (it
> must be empty), etc.  In a nutshell, your construct assumes that the buffer
> itself is temporary, whereas the only real need for our problematic use case is
> that the buffer's _display_, in a separate frame, be temporary.

The buffer need not be temporary.  But in order for quitting to get rid
of the frame, the buffer must be killed.

> IOW, I think your solution is more constraining/limited and doesn't really
> address the general problem, which is that of displaying _any_ buffer for only
> informational use (at least initially, allowing for user/code to intentionally
> switch focus to it).  And AFAIK the problem we are trying to solve occurs only
> when such a buffer appears in its own frame.
>
> Your solution certainly helps for things like *Process List* and *Marked Files*.
> But the characterization of the problem is, logically, in terms of a buffer that
> is displayed temporarily during a minibuffer dialog, in its own frame, and whose
> frame should not have the input focus in that context.
>
> Am I wrong about that?

If you came up with a macro that (approximately) does what you
want/need, I probably could answer that question.

> Don't get me wrong.  I think your code (the little that I've tried using it) is
> a definite improvement for the problem cases we've actually encountered, which
> are in fact not only temporary displays of a buffer but also displays of a
> temporary buffer.
>
> I'm just saying that I think the problem of MS Windows giving the focus to a new
> frame that gets popped during a minibuffer interaction, where that new frame
> should not have the focus, i.e., where its buffer is shown only for information,
> is more general than the show-a-temporary-buffer case you have treated.
>
> At least that's what I think so far.  You'll tell me if I'm wrong.

You might be right.

>> It's not that simple. The invoking code doesn't care about focus
>
> It does care.  Maybe what you mean is that it does not expect the focus to be
> messed with by MS Windows.

The invoking code does not care.  It expects `display-buffer' and
`yes-or-no-p' to take care of this.

> Typically, such code simply does not expect (take into account) a scenario where
> the user (a) has a standalone minibuffer frame, (b) has the buffer in question
> be popped up in its own frame, and (c) is on MS Windows, which steals the input
> focus and gives it to the new frame.
>
> But the code does expect the minibuffer to have the focus, and it knows that the
> buffer is shown only for informational purposes, i.e., the buffer does not need
> (and should not have) the input focus.

Once more - the code expects the underlying mechanism to handle that.

> The code does not, today, explicitly express that intention/care, because
> outside of the problematic case of (a), (b), and (c), which today is not that
> common, there is no need to express and handle that intention.  IOW it cares,
> but its cares are already taken care of automatically in most cases.
>
>> and in particular not about some frame whose eventually popping
>> up will cause problems.  It expects the reading from the minibuffer
>> mechanism DTRT.
>
> Precisely.  And except for the problematic case, there has never been any need
> for the programmer to make clear the fact (intention) that the buffer is
> informational only.
>
> You have encapsulated precisely that intention in your code.  But you have gone
> beyond that and expressed the additional intention that the buffer be temporary.

So write a `with-buffer-window' doing things in a non-temporary fashion.
The problem is that removing the frame without killing the buffer will
be impossible unless we provide yet another option.

> And your code in fact does make the distinction between *Process List* and
> *Backtrace*, which proves my point here.  But your code makes the distinction
> based on *Process List* being a temporary buffer (which it is), and not on it
> being a buffer that is displayed temporarily in its own frame.
>
> The latter distinction is I think the right one, and which would be good to
> handle.  That is where MS Windows's automatic focusing leads to a problem.
>
> The problematic case is (a) standalone minibuffer (b) popped-up buffer in its
> own frame, (c) that frame being new, and (d) the OS giving the new frame the
> input focus.

You still have to tell me how to remove that frame when you're done.

> The second step, I think, would be something similar, but not limited to
> temporary buffers.  Some way for a programmer to express the intention of
> displaying a buffer (temporary or not) only for informational purposes during a
> minibuffer interaction.
>
> And I think that for that more general case, there is a problem to be handled
> only when (a) there is a standalone minibuffer frame, (b) the buffer is popped
> up in its own frame.

Write the macro and we'll see further.

martin




This bug report was last modified 12 years and 288 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.