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

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

bug#11566: 24.0.97; `read-from-minibuffer': focus to standalone minibuff


From: martin rudalics
Subject: bug#11566: 24.0.97; `read-from-minibuffer': focus to standalone minibuffer frame?
Date: Sun, 27 May 2012 15:22:21 +0200

> On MS Windows at least, when a new frame is created it grabs the input
> focus.  The problem where the minibuffer frame does not get the focus it
> needs seems to arise in a situation where a new frame is popped up and
> then `read-from-minibuffer' is called immediately afterward.  Maybe
> there is some kind of contention or delay/race problem here (?) - I have
> no idea.

You should be able to check this by inserting a (sit-for 1) somewhere in
between popping up the frame and calling `read-from-minibuffer'.

> For example, `dired-mark-read-string' calls `dired-mark-pop-up' to read
> a string using `read-from-minibuffer' (`r-f-m' is the FUNCTION arg
> passed to `d-m-p-u' in this case).
>
> Inside a `save-window-excursion', `dired-mark-pop-up' then calls
> `dired-pop-to-buffer', which pops up a new buffer, which (let's say,
> because of `special-display-regexp' or whatever) is shown in a new
> frame.  MS Windows gives this frame the input focus.
>
> Then, still inside the `save-window-excursion', `dired-mark-pop-up'
> immediately calls the FUNCTION arg, which in this case is
> `read-from-minibuffer'.  (It does this using (apply FUNCTION args), but
> that should not make any difference.)
>
> [I don't think it matters for correctness whether the (apply FUNCTION
> args) is inside the `save-window-excursion'.  I've tried moving it
> outside, but that did not change anything.  I would think that it should
> be outside logically (why perform the action from that buffer?), but I'm
> not knowledgeable about all use cases of `dired-mark-pop-up'.]

IIRC _you_ don't need the `save-window-excursion'.  So replace it with a
`progn' and I'm sure you won't notice any difference.

> OK, so what happens is this: When `read-from-minibuffer' does its thing,
> the standalone minibuffer does not receive the user input.  Instead, the
> input goes to the popped-up frame (which has a list of *Marked Files*).
>
> That seems to be an exception to the general rule that
> `read-from-minibuffer' correctly moves the focus to the minibuffer - and
> to its frame.

IIUC `read-from-minibuffer' uses `redirect-frame-focus' to send the
keystrokes to the minibuffer window.  If that function works for you in
general, we likely have a race condition in this special case.

> I don't know why there is a difference in this case, but
> that seems to be what happens.  The problem is not specific to this
> example - it can occur at other times.  But I think that this is a good
> case to follow what's happening.
>
> I've tried various workarounds, with more or less success.  But I'm
> thinking now that the problem is not in any such functions that pop up a
> frame etc. but rather with `read-from-minibuffer' itself.  Shouldn't it
> have the responsibility here to give the minibuffer frame the focus?

Yes.  But the window manager must not intercept it.

> Here is a workaround I've come up with when trying to "fix" `r-f-m'
> itself:
>
> (defadvice read-from-minibuffer (around focus-standalone-minibuf activate)
>   "..."
>   (let ((selframe  (selected-frame))
>         result)
>     (unwind-protect
>          (progn (when (and (boundp '1on1-minibuffer-frame)
>                            (frame-live-p 1on1-minibuffer-frame))
>                   (select-frame-set-input-focus 1on1-minibuffer-frame))
>                 (setq result  ad-do-it))
>       (ignore-errors (select-frame-set-input-focus selframe))
>       result)))
>
> (In my case I know that the standalone minibuffer, if it exists, is the
> value of `1on1-minibuffer-frame'.  Not sure how the use of a standalone
> minibuffer would be detected in general - presumably by checking for a
> frame that has a `minibuffer' parameter with value `only'...)
>
> But that defadvice does not always make `r-f-m' DTRT, in any case.  For
> example, if the originally selected frame is deleted during `ad-do-it',
> then it punts and leaves the input focus in the minibuffer frame.  What
> I would probably expect (want) in that case is for the previously
> selected frame to get the focus.

I'm afraid that in this special case the current code will fail as well.

> For example, if I tweak `dired-mark-pop-up' so that it deletes the
> popped up frame at the end, then - since that frame was selected (by the
> window manager) when `read-from-minibuffer' was called - the minibuffer
> frame ends up with the focus.
>
> (And I do tweak `d-m-p-u' that way, because of another problem with such
> a popped up frame - see bug #7533.)
>
> Any help is appreciated.  Hope I've made the problem clear enough,
> though you would probably have to be on Windows to see it manifested.
> I really hope that someone with better understanding than I can help.

Try the sit-for approach.  Try to make a standalone example like

(let ((old-frame ... some existing frame))
  (make-frame)
  (redirect-frame-focus old-frame))

and see whether it fails giving focus to `old-frame'.

martin





reply via email to

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