From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Drew Adams" Newsgroups: gmane.emacs.bugs Subject: bug#11939: 24.1; `save-buffers-kill-emacs' loses minibuffer focuswhenit calls `list-processes' Date: Fri, 3 Aug 2012 09:46:53 -0700 Message-ID: <6461CCBF29034160B48D267E46D6FF0E@us.oracle.com> References: <83r4s2zcp9.fsf@gnu.org><81CFBB36FDCB4CD6B3762F9E00AC8290@us.oracle.com><83fw8iz7et.fsf@gnu.org><60948DD3935D452F85F95174474D06E9@us.oracle.com><838veaz34x.fsf@gnu.org><83629blssa.fsf@gnu.org>!<5011116B.4010106@gm x.at><32A934E820BA4853B84229C32F7145A1@us.oracle! ! .com><50116AD9.706 09@gmx.at><548032D12CE14E3689257D609E93482F@us.oracle.com><501175C9.3090803@gmx.at><2F76545DBD0C4F199A60F4B750709112@us.oracle.com><5012362A.7070200@gmx.at><4FB29D967D524DA99545D98266DD74B4@us.oracle.com><501540D0.50900@gmx.at><9E8DDE70EE6047779A17AA79E42D0FBA@us.oracle.com><50156DFE.6090807@gmx.at> <50165035.409040 1@gmx.at> <501BAAB0.1020! 807@gmx.at> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Trace: dough.gmane.org 1344012454 25202 80.91.229.3 (3 Aug 2012 16:47:34 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Fri, 3 Aug 2012 16:47:34 +0000 (UTC) Cc: 11939@debbugs.gnu.org To: "'martin rudalics'" Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Fri Aug 03 18:47:34 2012 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1SxL2D-0000hV-L3 for geb-bug-gnu-emacs@m.gmane.org; Fri, 03 Aug 2012 18:47:33 +0200 Original-Received: from localhost ([::1]:41493 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SxL2C-0001mC-Ls for geb-bug-gnu-emacs@m.gmane.org; Fri, 03 Aug 2012 12:47:32 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:51939) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SxL28-0001m7-Qd for bug-gnu-emacs@gnu.org; Fri, 03 Aug 2012 12:47:30 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SxL26-00043c-2k for bug-gnu-emacs@gnu.org; Fri, 03 Aug 2012 12:47:28 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:50127) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SxL25-00043Y-UB for bug-gnu-emacs@gnu.org; Fri, 03 Aug 2012 12:47:26 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.72) (envelope-from ) id 1SxL9R-0005iH-Tx for bug-gnu-emacs@gnu.org; Fri, 03 Aug 2012 12:55:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: "Drew Adams" Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 03 Aug 2012 16:55:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 11939 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 11939-submit@debbugs.gnu.org id=B11939.134401288421939 (code B ref 11939); Fri, 03 Aug 2012 16:55:01 +0000 Original-Received: (at 11939) by debbugs.gnu.org; 3 Aug 2012 16:54:44 +0000 Original-Received: from localhost ([127.0.0.1]:59673 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1SxL99-0005hn-Hp for submit@debbugs.gnu.org; Fri, 03 Aug 2012 12:54:44 -0400 Original-Received: from rcsinet15.oracle.com ([148.87.113.117]:27652) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1SxL95-0005ha-8L for 11939@debbugs.gnu.org; Fri, 03 Aug 2012 12:54:41 -0400 Original-Received: from acsinet22.oracle.com (acsinet22.oracle.com [141.146.126.238]) by rcsinet15.oracle.com (Sentrion-MTA-4.2.2/Sentrion-MTA-4.2.2) with ESMTP id q73Gl0sU029462 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 3 Aug 2012 16:47:01 GMT Original-Received: from acsmt356.oracle.com (acsmt356.oracle.com [141.146.40.156]) by acsinet22.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id q73GkxdJ008666 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 3 Aug 2012 16:47:00 GMT Original-Received: from abhmt119.oracle.com (abhmt119.oracle.com [141.146.116.71]) by acsmt356.oracle.com (8.12.11.20060308/8.12.11) with ESMTP id q73GkwKe031455; Fri, 3 Aug 2012 11:46:58 -0500 Original-Received: from dradamslap1 (/10.159.171.30) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 03 Aug 2012 09:46:58 -0700 X-Mailer: Microsoft Office Outlook 11 Thread-Index: Ac1xZHUqYzw1+y7KTxmQqSUc3/iQOwAH2Mhw X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.6157 In-Reply-To: <501BAAB0.1020807@gmx.at> X-Source-IP: acsinet22.oracle.com [141.146.126.238] X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:62793 Archived-At: > The problem happens in the following scenario: > > (1) The application requests (implicitly) to make a new frame. > > (2) The application ask to read from the minibuffer with some > old frame selected. In this case the statement above does not > redirect focus because either the old frame is the minibuffer > frame or the old frame's focus is already redirected to the > minibuffer frame. > > (3) Emacs eventually selects the new frame in `handle-switch-frame'. > > After that, the new frame gets the keystrokes for reading from the > minibuffer but Emacs won't find a redirection in kbd_buffer_get_event. Agreed; that is what we have been discussing. > the idea of doing > (when (eq (selected-frame) > (window-frame (minibuffer-window))) > > means that when you pop up a new frame when a non-minibuffer frame is > selected you never redirect, while you always redirect when the > minibuffer frame is selected. This conditioning cannot always work > correctly IMHO. Which is what I said in my last message. It must not be done systematically. I gave the counter-example of a *Backtrace* frame. 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). 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 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. 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. 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. Likewise, nothing should prevent the user from explicitly switching the focus to BUFFER's frame. 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. 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 during BODY (unless that is done by the user or by code within BODY). 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 cannot be made explicit then there is no way to know what TRT is. 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. > >> > That's the best thing I've come up with, but perhaps you > >> > have a suggestion. `after-make-frame-functions' seems > >> > like the right place to do the deed, because it knows > >> > about the new frame, which is the one whose focus needs > >> > to be redirected. > > > > I want to say "ONLY IT knows..." (among existing hooks), but I am not > > sure of that. IOW, of the hooks I am aware of, this one seems the > > most pertinent here. > > It knows that a new frame will be constructed. But it does not know > whether focus shall be redirected. 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." > >> > Again, this all seems to underline the need for a > >> > notion/mechanism of defining or detecting a user dialog > > > > I think you are probably right that "detecting" might be a > > pipe dream. What I really have had in mind is mentioned above: > > the code would encapsulate a minibuffer reading that might > > pop up an informational window, By "might pop up" I meant that _if_ informational BUFFER is popped up in its own 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? 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. > >> > that uses the minibuffer while popping up an informational > >> > frame only for the duration of the minibuffer interaction > >> > (input). > > > > The important point here is "informational...only". > > > > And this is where I need to mention an example of why it > > is not a solution to do this redirection systematically, testing only > > (when (eq (selected-frame) (window-frame (minibuffer-window))). > > > > A case in point is the debugger. In my setup *Backtrace* > > pops up in a special-display frame. It is not the case that this > > buffer is for information only. It is truly necessary that > > *Backtrace* receive the focus. > > Is it? I never gave it a thought. Yes, it seems to be necessary. The proof being that when I applied my partly misguided "fix" systematically the *Backtrace* frame lost the focus to the minibuffer frame and I could not use it. I had to click the *Backtrace* frame to give it back the focus. > But I perfectly understand that when *Backtrace* pops up you > don't want to redirect focus to the minibuffer frame. Correct. *Backtrace* is not popped up for info only. It is popped up for interacting with the user. It is supposed to have the input focus, even if it is popped during a minibuffer interaction. Note that this is not really an example of what I meant above by Emacs code within BODY being able to switch focus to BUFFER, because *Backtrace* would not be invoked using `with-unfocused-buffer-displayed'. It is not the intention that it be displayed for info only. But it is an example of why systematically redirecting the focus to the minibuffer frame from any new frame that pops up when the minibuffer is active is not TRT. > > So this is a good case where my redirection "fix" does not do > > the right thing. > > If you hardwire redirection in `after-make-frame-functions', > you get bad results in the case where the redirection is not wanted. Correct. That is what I was saying too. Systematic or hard-wire is not appropriate. The first lesson (for me) was learning that it can only be appropriate when the minibuffer is active. The second lesson was that even when the minibuffer is active it might not be appropriate. In the end, it is only the programmer who knows whether some buffer that is popped up should be denied the input focus. > 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.) > `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. > Older application don't and that's our trouble. That's one problem. Admittedly, that can be looked at as a nice-to-have, and I might be the only person who cares much about that. 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'. 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'. 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. 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? 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. > > It is only the code that invokes reading from the minibuffer > > and pops up the other window/frame that can know whether the > > focus should be in that window/frame or in the minibuffer. > > 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. 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. 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. That's fine, but it is less general: there are (at least logically) problematic cases that it does not solve, namely, popping up an existing, non-temporary buffer temporarily during a minibuffer query of the user. > > But here's the thing: in the case of windows instead of > > frames, Emacs DTRT, no? Emacs distinguishes the case of > > window *Process List* from window *Backtrace*, > > giving the focus to the latter and not to the former. Why > > can't we make Emacs DTRT for frames, just as it does for windows? 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. > For windows on the same frame we can differ between > `display-buffer' and `pop-to-buffer'. For windows on different > frames we have the complication that the `handle-switch-frame' > event triggered by the OS causes Emacs to select that frame, > that is, implicitly replace `display-buffer' by `pop-to-buffer'. Yes, that is one way to put it. > > I know that MS Windows altering the focus throws a monkey > > wrench into the mix, but surely we can find some way to KEEP > > the focus (i.e. re-focus if necessary) where Emacs put it > > (correctly). > > As far as old code is concerned you probably are overly optimistic. OK, let's say that that is a nice-to-have, and move on. The first step is your code, which handles a subset of the problematic cases for new Emacs releases. Very good. 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.