bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#11939: 24.1; `save-buffers-kill-emacs' loses minibuffer focuswhenit


From: martin rudalics
Subject: 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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]