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: Drew Adams
Subject: bug#11939: 24.1; `save-buffers-kill-emacs' loses minibuffer focuswhenit calls `list-processes'
Date: Sun, 5 Aug 2012 18:11:39 -0700

> 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.

Again, AFAIK there is no problem if the user does not use a standalone
minibuffer.  A user with a standalone minibuffer is the problematic use case,
and the only one I am really concerned about.  AFAIK, whatever exists already
is, I assume, OK for other use cases.

So what you say here about such use cases ("users who want to pop up a frame
with a minibuffer") is irrelevant to the discussion, or at least to my part of
it.  If you think there is also a problem for such cases, fine, but I cannot
speak to that.  I am interested in the case that I reported, i.e., for users
with a standalone minibuffer frame.

> 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.

Which is why I have been saying that it will need to be about restoring focus to
the minibuffer, rather than preventing focus from leaving it.  We've already
been around this barn a couple times now, no?  MS Windows presumably takes the
focus away, and there is apparently nothing we can do to prevent that.  So
what's needed is to try to put the focus back where it belongs, if that happens.

>  > 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.
> 
> ... 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.

Yes, but I don't see how that is relevant here.  The point is that a developer
would have some way to indicate the _intention_ that the minibuffer retain the
focus.

Where and how the informational buffer is displayed should be taken into
consideration in _defining_ the macro or whatever that developers would use.
But the developer would not be concerned with where or how the buffer is
displayed.  All the developer would need to communicate is the intention that
the minibuffer have the focus.

> For a use case where the frame of the displayed
> buffer should have input focus see the `pop-up-frames' non-nil case.

Dunno what that means.  That seems irrelevant here.  In particular, I use that
case (non-nil p-u-f), and I can tell you that there are cases (e.g. *Backtrace*)
where the buffer that is popped up in its own frame should have the input focus,
and there are cases (e.g. *Process List*) where it should not.

>  > 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 

I really do not follow you, sorry.  Are you talking about minibuffer input?

I am talking _only_ about the case of users who have a standalone minibuffer
frame.  That is the problematic case that we have (I think) been discussing from
the beginning.

> but prefer answering the dialogs we talk about here in a minibuffer 
> frame with the list of files being displayed in the same frame.

Sorry, I am quite lost.  What "list of files"?

Here's a wild guess (ignore, if it is wrong and does not save us time): You are
introducing something new, which is the possibility that a user with a
standalone minibuffer frame might, in some situations, NOT want minibuffer input
and echo-area messages to take place in the standalone minibuffer frame.

Is that it?  If so, I would respectfully request that we drop that like a hot
potato.  There is zero request for such a feature AFAIK.  I know of no such user
- do you?

If you are interested in that and convinced that there is demand for it, you can
always pursue it as an option after this bug gets fixed.

I have no objection to the creation of such a new feature, but let's first solve
the problem encountered.

> The new option, let's call it
> `always-redirect-input-to-standalone-minibuffer-frame', if non-nil,
> could be used by your construct.

No, please.  What I am describing is not about _always_ redirecting input focus
to a standalone minibuffer frame.  The *Backtrace* example speaks to why that is
not appropriate.

It is about redirecting (retaining/restoring, really) input focus to that frame
ONLY for _minibuffer_ input.

In sum, it is about respecting the standalone minibuffer.  If a user creates a
standalone minibuffer frame then s?he does not want other minibuffers created on
other frames.

>  > 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?

Sorry, I don't know what that means.  Perhaps give an example of what you mean
by temporarily selected and current?

>  > 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?

No, not as I was conceiving it.  I suppose that would be a possibility, but I
expect it is better to keep buffer display out of it.  That's why I said things
like "_if_ BUFFER gets displayed in its own frame".

What I had in mind was that the macro would be responsible only for making sure
that minibuffer input gets (re-)directed to the minibuffer frame.  And that goes
for any code in BODY, including code that might pop up BUFFER.

IOW, display of BUFFER would come (if it came) from BODY.

But again, I'm just thinking out loud.  And it's probable that you see things
that I do not.

>  > 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.

Can you elaborate?  I don't follow.

All that I am saying is that we try to provide some kind of a construct that
says:

1. Evaluate BODY.

2. But while doing that, _if_ BUFFER gets displayed, then ensure that its
minibufer input (if the minibuffer is used) is directed to the standalone
minibuffer frame.

IOW, the use of this construct distinguishes the *Process List* case from the
*Backtrace* case: The construct would be used for display of *Process List*,
since we do not want that buffer to get the input focus.  The construct would
not be used for the *Backtrace* case.

But I'm open to other suggestions.

>  > 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.

That's not a solution at all.  Again, we're talking about minibuffer input,
i.e., input with the minibuffer active, and input that is intended to be read in
the minibuffer.  The aim is to get the focus moved to the minibuffer frame.

I am not looking for the creation of minibuffers on other frames.  I am looking
for a fix to the problem that the minibuffer frame is not getting (or
retaining?) the focus it needs when minibuffer input is called for.

>  > 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 ...

Yes.

>  > 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.

No.  Again, during reading from the minibuffer it is quite possible for a user
to interact with other buffers and their frames.  I gave the example of
*Completions*.  The user can hit a key or use the mouse to change the input
focus temporarily to another frame - any frame.

When the user does that s?he is executing code within BODY.  It is code that
reads from the minibuffer, but also code that implements any commands bound to
keys or mouse actions that the user uses during that minibuffer dialog.  That's
all I meant.

>  > 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?

The person who writes the code that reads from the minibuffer, code that might
or might not be wrapped in the new macro, i.e., that might or might not want to
stipulate that BUFFER is not to receive the input focus.

>  > 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.

As one programmer, I care.

But I agree that it will be difficult to get programmers to be sensitive to the
possibility that some users have a standalone minibuffer and some OS's might
steal focus and give it to new frames that are popped up.

This is nothing new - Emacs developers tend not to even consider the non-nil
`pop-up-frames' case (or its Emacs 24+ equivalent) when they implement a new
feature.  For a poster-child example, see bug #12139.

But if things start to work better, more seamlessly, for Emacs with frames and a
standalone minibuffer, then maybe more users will opt for that.  And that will
perhaps mean that more programmers will naturally think to test such use cases
as well.  I can only continue to hope.

> 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.

Agreed.  My description is vague not because I want the moon but because I don't
know what the implementation might look like.  If I get something that is better
I'll be happy, even if it is not perfect.

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

Of course.  We are only talking about the case where there is a standalone
minibuffer frame.  That is THE minibuffer - THE place where users look for input
queries and output messages.  All other frames are minibuffer-less.  Or they
should be.

Not being able to use the standalone minibuffer in some context, and having to
use another minibuffer somewhere else, would be a degraded mode, just a
workaround.  Better than nothing, perhaps (perhaps), but it does not respect the
standalone minibuffer or the user who called for it.

>  > 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.

I'd rather you didn't.  Let's not bring in new things.

The problem is that the minibuffer is not getting the focus it needs.

There is no request for some additional, proxy minibuffer to appear somewhere
else.  That's not TRT.

You have a perfectly good, brand new car that runs fine.  You can drive it
everywhere except that there is one bridge that is broken near your home.  You
just cannot get home by car using that bridge.

What is offered as help is for you to wait at the washed-out bridge for a
helicopter that comes once a day and can take you across the river.  That's a
temporary workaround, and it might be welcome, but it is not a real solution.
The solution that is needed is for the bridge to be fixed.

>  > 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.

I don't know.  The only problems I am aware of for `w-t-b-w.el' are these:

1. Loss of special-displayness (a separate problem, but important if we're
talking about `w-t-b-w.el' as it stands now).

2. The fact that it limits itself to display of temporary buffers, whereas the
actual problem has to do with the temporary display of buffers.

Unless I'm missing something, it does not have the problem (from my point of
view) that the frame popped up has its own minibuffer.  And that's good.  I
mention this because you keep mentioning that as a possibility.  I'm glad that
`w-t-b-w.el' does not make that happen.  

When I use `w-t-b-w.el' with the *Process List* thing it correctly prompts for
the answer in the minibuffer frame.  Dunno whether that is just because that is
a `yes-or-no-p' thing or whether the problem does not exist in general.  After
the special-display bug is fixed I'll try to use `w-t-b-w.el' more, to see.

Anyway, if `w-t-b-w.el' has no other problems than #2, and if #1 is fixed, then
I can certainly live with it.  And I will appreciate it!  Ideally I would like
something that I can also use with other Emacs versions, but as I said, that's
just a nice-to-have.

So I would say that if anything I've said suggests to you that you might be able
to improve `w-t-b-w.el' so that it handles an arbitrary buffer and not just a
temporary buffer, that would be great.  If not, then let's at least get
`w-t-b-w.el' into Emacs (after fixing the special-display bug).  That will be a
big improvement and much appreciated, by me at least.

Can you fix the special-display bug, so that I will be able to use `w-t-b-w.el'
more, to let you know if I encounter other problems?

And as far as you know, is the fact that the minibuffer frame is still used (as
it should be) due only to the fact that `yes-or-no-p' is used, or can I expect
that the minibuffer frame will be used in general?

>  >> 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?

I'm afraid I cannot help here.

>  >> `with-temp-buffer-window' avoids that by asking the
>  >> `yes-or-no-p' question in the new frame.

Dunno why I (or was it you?) said that.  I see the question in the minibuffer
frame, not the new frame.  Which is TRT.

>  > 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

I'm afraid I cannot come up with the macro.  I was hoping that my description of
what would be good might inspire you. ;-)

> based on that option (I'm afraid I do not
> understand well what you think that macro's BODY should do).

I know I was vague, but I do not know what needs to be done in terms of
implementation.  If my description, including above, doesn't help, forget about
this enhancement.

>  > 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?

Yes, it is more restrictive than the actual problem encountered.  As I said, it
might suffice in practice, but there is nothing in the problem description that
requires that the buffer itself be temporary.

Yes, *Process List* and *Marked Files* are temporary.  But there is no reason to
suppose that we will never want to temporarily display some non-temporary buffer
without giving it the input focus.

>  > 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.

That's great.  I have no objection to it.  I was just saying that it corresponds
to a set of use cases that is a subset of the use cases where the input-focus
switch (by MS Windows) will present a problem.

>  > 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.

In that, it is temporary.  Also in the fact (IIUC) that it is empty/emptied to
start with.

>  > 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.

Let's move one step at a time.  I can't really help with coming up with the
macro that I imagine vaguely.  And you are having difficulty seeing what I'm
getting at, which might well be an indication that I am mixed up a bit.

Why don't you try to fix the special-display bug in your code, and then I'll use
it a bit more to see if I encounter other problems.  If not, then it would be
good if you added it to Emacs.  After that, we can always discuss any further
enhancements or other improvements, in a different thread or off list.

I think that most of what I've tried to say you understand, so if in the future
you do see a possibility of generalizing the fix etc. then you might want to do
so.  I cannot really expect more than to make myself understood so that you can
keep the wish in mind.

>  >> 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.

In the general case it is not `yes-or-no-p'.

But OK, I think we are saying the same thing, using different words.

>  > 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.

If you agree with the last paragraph I wrote, then fine.  I think we are saying
the same thing.  I certainly agree that the invoking code should not have to
care about setting/changing focus.  By "it cares" I meant only that it cares
that the minibuffer have the focus - it expects that.   It does not care/want to
have to manage the focus itself.  It "expects the underlying mechanism to handle
that."

The code's intention that the minibuffer receive the input is not something that
programmers should have to express.  But I see no way around that if MS Windows
gets in the middle and moves the focus around.  But if you can make sure that
there is no need to express such an intention in the code explicitly, so much
the better.

I was expecting that such expression would enable us to DTRT wrt focus
redirection, e.g. to distinguish the *Process List* case from the *Backtrace*
case.  But if that's not necessary, good.

>  > 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.

See above.

> The problem is that removing the frame without killing
> the buffer will be impossible unless we provide yet another
> option.

Maybe it's good that we talk about this more general case later.  I don't want
the ideal to become the enemy of the good.  I would like to see your current
solution applied to Emacs before we get too far afield.

>  > 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 informational frame?  I'd vote for `delete-frame', at least for my own use.
We might want to provide ways for the caller and/or the user to control both
what to do with the frame/window and what to do with the buffer.  But maybe
`frame-auto-hide-function' would make sense here?

Anyway, let's talk about this later.






reply via email to

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