unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#26513: 25.2; pop-up-frames and *Completions* buffer
@ 2017-04-15  9:17 Charles A. Roelli
  2017-04-15 14:50 ` martin rudalics
                   ` (2 more replies)
  0 siblings, 3 replies; 26+ messages in thread
From: Charles A. Roelli @ 2017-04-15  9:17 UTC (permalink / raw)
  To: 26513

From emacs -Q:

M-x set-variable RET pop-up-frames RET t RET
M-x global- TAB

The *Completions* buffer is opened in a new frame, but the cursor is in
the frame too, so the user has to switch back to the minibuffer to
continue typing.

How can the user ensure that the cursor goes back to the minibuffer
automatically?  Could the solution be documented somewhere (maybe in the
docstring of `pop-up-frames') or could the completion code take care of
it?

In GNU Emacs 25.2.1 (x86_64-apple-darwin10.8.0, NS appkit-1038.36 Version 10.6.8 (Build 10K549))
 of 2017-02-22 built on gray
Windowing system distributor 'Apple', version 10.3.1038
Configured using:
 'configure --with-modules'

Configured features:
JPEG RSVG NOTIFY ACL GNUTLS LIBXML2 ZLIB TOOLKIT_SCROLL_BARS NS MODULES





^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2017-04-15  9:17 bug#26513: 25.2; pop-up-frames and *Completions* buffer Charles A. Roelli
@ 2017-04-15 14:50 ` martin rudalics
  2017-04-15 19:14   ` Charles A. Roelli
  2017-04-15 16:49 ` Drew Adams
  2022-02-15 10:37 ` Lars Ingebrigtsen
  2 siblings, 1 reply; 26+ messages in thread
From: martin rudalics @ 2017-04-15 14:50 UTC (permalink / raw)
  To: Charles A. Roelli, 26513

 > M-x set-variable RET pop-up-frames RET t RET
 > M-x global- TAB
 >
 > The *Completions* buffer is opened in a new frame, but the cursor is in
 > the frame too, so the user has to switch back to the minibuffer to
 > continue typing.
 >
 > How can the user ensure that the cursor goes back to the minibuffer
 > automatically?  Could the solution be documented somewhere (maybe in the
 > docstring of `pop-up-frames') or could the completion code take care of
 > it?

This use of *Completions* seems strange in another way: When I click on
one of the items in the *Completions* buffer or type RET on it, the
respective mode is enabled and the *Completions* frame stays around.  Is
that the desired behavior?

martin





^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2017-04-15  9:17 bug#26513: 25.2; pop-up-frames and *Completions* buffer Charles A. Roelli
  2017-04-15 14:50 ` martin rudalics
@ 2017-04-15 16:49 ` Drew Adams
  2017-04-15 20:05   ` Charles A. Roelli
  2022-02-15 10:37 ` Lars Ingebrigtsen
  2 siblings, 1 reply; 26+ messages in thread
From: Drew Adams @ 2017-04-15 16:49 UTC (permalink / raw)
  To: charles, 26513

FWIW, I reported such problems a couple of decades ago.
Unfortunately (for me at least), there is not enough
use or interest in using separate frames by default,
including for *Completions*, so this kind of thing has
not gotten the love it would really need for progress.

I've tried to do what I can in my own environment to
handle this, especially in the context of a standalone 
minibuffer frame.  And Martin has been helpful wrt
problems that resulted from changes in the Emacs code
over the years.

Here's what I do for *Completions*, FWIW:

I add an entry to `special-display-buffer-names* that
has a function, `1on1-display-*Completions*-frame',
which takes care of displaying the *Completions* frame.

The main thing that function does is redirect the
focus of the *Completions* frame to the standalone
minibuffer frame (if the minibuffer is active) or
(if not) to the buffer that was current before
*Completions* display was requested:

(let ((redirect
       (if (active-minibuffer-window)
           1on1-minibuffer-frame
         (and completion-reference-buffer
              (get-buffer-window
                completion-reference-buffer 'visible)
                (not (eq (get-buffer "*Completions*") 
                         completion-reference-buffer))
                (window-frame
                  (get-buffer-window
                    completion-reference-buffer t))))))
      (when redirect
        (redirect-frame-focus (selected-frame)
                              redirect)))

I've said it before, but I think it is relevant:
Back in the early 1990s the Emacs implementation
named `Epoch' worked very well with a standalone
minibuffer frame, out of the box.

All I've done is try to work around Emacs's poor
(non-existent) support for this kind of use case -
essentially trying to emulate Epoch behavior.

But frames remain the poor cousin to windows in
Emacs.  Part of that is likely due to the fact that
Emacs cannot completely control the behavior of
frames for all window managers.  Window mgrs are
different, and they have ultimate control.

The other reason is probably just because few Emacs
users try to use separate frames by default, or if
they try they soon give up due to the many hurdles.

Anyway, you might try, to start with, redirecting
the frame focus back to `completion-reference-buffer'.

For reference, in case it helps, my code for
`1on1-display-*Completions*-frame' is in `oneonone.el'
(https://www.emacswiki.org/emacs/download/oneonone.el).
My code for keybindings in `completion-list-mode-map'
is in `icicles-mode.el'
(https://www.emacswiki.org/emacs/download/icicles-mode.el).





^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2017-04-15 14:50 ` martin rudalics
@ 2017-04-15 19:14   ` Charles A. Roelli
  2017-04-15 19:40     ` martin rudalics
  0 siblings, 1 reply; 26+ messages in thread
From: Charles A. Roelli @ 2017-04-15 19:14 UTC (permalink / raw)
  To: martin rudalics; +Cc: 26513

On Sat, Apr 15 2017 at 04:50:33 pm, martin rudalics wrote:

>> M-x set-variable RET pop-up-frames RET t RET
>> M-x global- TAB
>>
>> The *Completions* buffer is opened in a new frame, but the cursor is in
>> the frame too, so the user has to switch back to the minibuffer to
>> continue typing.
>>
>> How can the user ensure that the cursor goes back to the minibuffer
>> automatically?  Could the solution be documented somewhere (maybe in the
>> docstring of `pop-up-frames') or could the completion code take care of
>> it?
>
> This use of *Completions* seems strange in another way: When I click on
> one of the items in the *Completions* buffer or type RET on it, the
> respective mode is enabled and the *Completions* frame stays around.  Is
> that the desired behavior?

(The frame is iconified in this case for me.)  I wouldn't mind if the
frame just stayed where it was (i.e. no iconification), and I think this
can be done quite easily by overriding the function
`minibuffer-hide-completions', and possibly by dedicating the
*Completions* buffer to the window displaying it in its own frame
(otherwise it can happen that the frame ends up showing some other
buffer -- not yet sure how this happens).  Other ideas welcome, of
course.

I can imagine that some people would instead prefer to just hide the
*Completions* frame when it's not needed (by changing the frame
visibility parameter).  Or it could be shrunk to a small size when not
needed, and then resized to fit its new contents when summoned again.
There could be many different strategies.

For me, the advantage of a separate *Completions* frame would be that
you can place it once on your display at the start of your Emacs
session, and afterwards you never incur the cost of splitting windows,
creating frames or switching buffers for completions again -- and you
would always know where to look for them.  It could also be useful to
still have the *Completions* buffer in view /after/ completion has been
done -- say you hit C-x C-f TAB to see the files in the current
directory, then pick one and hit RET; if the *Completions* frame sticks
around, you can use it to get an idea of what other files are there.

But the main issue for now lies in focus being given to the
*Completions* frame when completion is initiated.  The equivalent with
`pop-up-frames' equal to nil would be if the *Completions* window was
selected after hitting TAB during completion.  It's not intuitive.





^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2017-04-15 19:14   ` Charles A. Roelli
@ 2017-04-15 19:40     ` martin rudalics
  2017-04-15 20:28       ` Charles A. Roelli
  0 siblings, 1 reply; 26+ messages in thread
From: martin rudalics @ 2017-04-15 19:40 UTC (permalink / raw)
  To: Charles A. Roelli; +Cc: 26513

 > (The frame is iconified in this case for me.)  I wouldn't mind if the
 > frame just stayed where it was (i.e. no iconification), and I think this
 > can be done quite easily by overriding the function
 > `minibuffer-hide-completions', and possibly by dedicating the
 > *Completions* buffer to the window displaying it in its own frame
 > (otherwise it can happen that the frame ends up showing some other
 > buffer -- not yet sure how this happens).  Other ideas welcome, of
 > course.

I must admit that I never use completion after M-x.  I was simply
stupefied by the fact that it immediately executed a command instead of
putting the command into the minibuffer, let me regard it and execute it
after I typed RET there.

 > But the main issue for now lies in focus being given to the
 > *Completions* frame when completion is initiated.  The equivalent with
 > `pop-up-frames' equal to nil would be if the *Completions* window was
 > selected after hitting TAB during completion.  It's not intuitive.

It should be now possible to do that on X and Windows by using the
'no-focus-on-map' parameter I added this week.  I'm not sure whether
such a thing exists for NS.  By default, a new Window Manager window
always gets focus.  Taking it away from the window right after creation
might be tricky, sometimes.

Still, why would you want to "continue typing in the minibuffer" when
the desired effect of what you do is to choose and execute one of the
commands shown in the *Completions* buffer?

martin





^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2017-04-15 16:49 ` Drew Adams
@ 2017-04-15 20:05   ` Charles A. Roelli
  2017-04-16 15:54     ` Drew Adams
  0 siblings, 1 reply; 26+ messages in thread
From: Charles A. Roelli @ 2017-04-15 20:05 UTC (permalink / raw)
  To: Drew Adams; +Cc: 26513

On Sat, Apr 15 2017 at 09:49:28 am, Drew Adams wrote:

> FWIW, I reported such problems a couple of decades ago.
> Unfortunately (for me at least), there is not enough
> use or interest in using separate frames by default,
> including for *Completions*, so this kind of thing has
> not gotten the love it would really need for progress.

Maybe it's time for some change?  :-)  Especially in light of the
boatload of new frame stuff that was added recently (thanks to Martin
for that).

> I've tried to do what I can in my own environment to
> handle this, especially in the context of a standalone 
> minibuffer frame.  And Martin has been helpful wrt
> problems that resulted from changes in the Emacs code
> over the years.
>
> Here's what I do for *Completions*, FWIW:
>
> I add an entry to `special-display-buffer-names* that
> has a function, `1on1-display-*Completions*-frame',
> which takes care of displaying the *Completions* frame.
>
> The main thing that function does is redirect the
> focus of the *Completions* frame to the standalone
> minibuffer frame (if the minibuffer is active) or
> (if not) to the buffer that was current before
> *Completions* display was requested:
>
> (let ((redirect
>        (if (active-minibuffer-window)
>            1on1-minibuffer-frame
>          (and completion-reference-buffer
>               (get-buffer-window
>                 completion-reference-buffer 'visible)
>                 (not (eq (get-buffer "*Completions*") 
>                          completion-reference-buffer))
>                 (window-frame
>                   (get-buffer-window
>                     completion-reference-buffer t))))))
>       (when redirect
>         (redirect-frame-focus (selected-frame)
>                               redirect)))

1) Does this still work without a standalone minibuffer frame?  I'm
   interested in using one, but I'd rather fix the *Completions* frame
   problem first before adding on a minibuffer-only frame to my setup.
2) I don't understand why vanilla Emacs puts the *Completions* buffer in
   focus when it's popped into a new frame -- but I know that this is
   the reason you have to redirect the focus from *Completions* to the
   minibuffer or the completion-reference-buffer frame.  On Mac OS,
   though, redirecting frame focus results in a lot of flicker and lag
   on each keypress -- sometimes up to a second or two long.  (Will save
   the rest for another bug report someday.)  Wouldn't a simpler
   alternative to frame redirection be to just put point back in the
   minibuffer or completion-reference-buffer?

> I've said it before, but I think it is relevant:
> Back in the early 1990s the Emacs implementation
> named `Epoch' worked very well with a standalone
> minibuffer frame, out of the box.
>
> All I've done is try to work around Emacs's poor
> (non-existent) support for this kind of use case -
> essentially trying to emulate Epoch behavior.

Standalone minibuffer frames are meant to work correctly almost out of
the box, though, right?  (IIRC you just have to fiddle with
`initial-frame-alist' to remove the minibuffer from the first
frame).  It's only when *Completions* is displayed in a separate frame
that there are issues.

> But frames remain the poor cousin to windows in
> Emacs.  Part of that is likely due to the fact that
> Emacs cannot completely control the behavior of
> frames for all window managers.  Window mgrs are
> different, and they have ultimate control.

Yes, this seems like it's the main issue here.  But still, sane frame
behavior doesn't seem too far off.





^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2017-04-15 19:40     ` martin rudalics
@ 2017-04-15 20:28       ` Charles A. Roelli
  2017-04-16  7:16         ` martin rudalics
  0 siblings, 1 reply; 26+ messages in thread
From: Charles A. Roelli @ 2017-04-15 20:28 UTC (permalink / raw)
  To: martin rudalics; +Cc: 26513

On Sat, Apr 15 2017 at 09:40:19 pm, martin rudalics wrote:

>> (The frame is iconified in this case for me.)  I wouldn't mind if the
>> frame just stayed where it was (i.e. no iconification), and I think this
>> can be done quite easily by overriding the function
>> `minibuffer-hide-completions', and possibly by dedicating the
>> *Completions* buffer to the window displaying it in its own frame
>> (otherwise it can happen that the frame ends up showing some other
>> buffer -- not yet sure how this happens).  Other ideas welcome, of
>> course.
>
> I must admit that I never use completion after M-x.  I was simply
> stupefied by the fact that it immediately executed a command instead of
> putting the command into the minibuffer, let me regard it and execute it
> after I typed RET there.

Really?  But selecting a completion with the mouse or with RET in the
*Completions* window with pop-up-frames set to nil does the same.
Granted, though, it's probably not a very common thing to do.

And also, sorry if this was not clear, but this bug is for completion
everywhere in Emacs, not just M-x.

>> But the main issue for now lies in focus being given to the
>> *Completions* frame when completion is initiated.  The equivalent with
>> `pop-up-frames' equal to nil would be if the *Completions* window was
>> selected after hitting TAB during completion.  It's not intuitive.
>
> It should be now possible to do that on X and Windows by using the
> 'no-focus-on-map' parameter I added this week.  I'm not sure whether
> such a thing exists for NS.  By default, a new Window Manager window
> always gets focus.

Thank you; I wasn't aware of this.  Now it makes sense why the
*Completions* frame gets focus.  One solution to this problem, then,
might be to create a separate *Completions* frame on startup and update
it with completions as necessary, without ever deleting/recreating it.
I'll see if I can write a mode or something for this.

> Taking it away from the window right after creation might be tricky,
> sometimes.
>
> Still, why would you want to "continue typing in the minibuffer" when
> the desired effect of what you do is to choose and execute one of the
> commands shown in the *Completions* buffer?

As explained above, it isn't necessarily the desired effect, only one
example.





^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2017-04-15 20:28       ` Charles A. Roelli
@ 2017-04-16  7:16         ` martin rudalics
  2017-04-17  7:44           ` Charles A. Roelli
  0 siblings, 1 reply; 26+ messages in thread
From: martin rudalics @ 2017-04-16  7:16 UTC (permalink / raw)
  To: Charles A. Roelli; +Cc: 26513

 > Really?  But selecting a completion with the mouse or with RET in the
 > *Completions* window with pop-up-frames set to nil does the same.

Yes.  But I never noticed.  I could have sworn that I had to type RET
somewhere to confirm that I really wanted to do what I picked with the
mouse or via RET in the *Completions* buffer before.

 > Granted, though, it's probably not a very common thing to do.
 >
 > And also, sorry if this was not clear, but this bug is for completion
 > everywhere in Emacs, not just M-x.

That's why I asked.  I now think that for most users the behavior that
the frame is selected is quite normal (for M-x) and I rather would
expect the *Completions* window to be selected too when it appears on
the same frame.  The current behavior is inconsistent.

 > Thank you; I wasn't aware of this.  Now it makes sense why the
 > *Completions* frame gets focus.  One solution to this problem, then,
 > might be to create a separate *Completions* frame on startup and update
 > it with completions as necessary, without ever deleting/recreating it.
 > I'll see if I can write a mode or something for this.

Even then it might get focus.  With a focus follows mouse policy, raising
a frame that happens to be under the mouse pointer will usually also
focus it (blame the window manager for that).

 >> Still, why would you want to "continue typing in the minibuffer" when
 >> the desired effect of what you do is to choose and execute one of the
 >> commands shown in the *Completions* buffer?
 >
 > As explained above, it isn't necessarily the desired effect, only one
 > example.

Maybe it would then make sense to discriminate the use cases of
*Completions*: One where continuing typing in the selected window
wouldn't make sense because one has to select an item in the
*Completions* buffer.  In that case selecting the *Completions* window
makes perfect sense IMHO.  And one where you usually want to continue
typing and the *Completions* buffer is just there for later perusal.

martin





^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2017-04-15 20:05   ` Charles A. Roelli
@ 2017-04-16 15:54     ` Drew Adams
  2017-04-18 17:27       ` martin rudalics
  2017-04-18 20:34       ` Charles A. Roelli
  0 siblings, 2 replies; 26+ messages in thread
From: Drew Adams @ 2017-04-16 15:54 UTC (permalink / raw)
  To: charles; +Cc: 26513

> 1) Does this still work without a standalone minibuffer frame?  I'm
>    interested in using one, but I'd rather fix the *Completions* frame
>    problem first before adding on a minibuffer-only frame to my setup.

I can make it work without a standalone minibuffer frame
in all Emacs versions before Emacs 25.  For some reason,
redirecting the frame focus does not seem to work right
for Emacs 25 when there is no standalone minibuffer frame.
I hope I'm just missing something simple.

The following code works, for example, except for Emacs 25.
(I have Emacs 25.1-2.)  Maybe you or Martin can explain why.
The debug `message' calls here don't tell me that anything
is wrong, but clearly something is.

I tried some variants also (no `w32-grab-focus-on-raise',
explicitly select *Completions* frame (and even set focus
to it temporarily), etc., to no avail.

(defun foo ()
  (interactive)
  (add-to-list 'special-display-buffer-names
               `("*Completions*" display-comp-fr))
  (setq w32-grab-focus-on-raise  nil))

(defun display-comp-fr (buf &optional args)
  (let ((return-window
         (select-window
          (funcall special-display-function buf args))))
    (raise-frame)
    (message "BUF: %S, WIN: %S, FR: %S"
             buf (get-buffer-window buf)
             (window-frame (get-buffer-window buf)))
    (let* ((mini-win  (active-minibuffer-window))
           (redirect
            (if mini-win
                (window-frame mini-win)
              (and completion-reference-buffer
                   (get-buffer-window
                    completion-reference-buffer
                    'visible)
                   (not (eq (get-buffer "*Completions*")
                            completion-reference-buffer))
                   (window-frame
                    (get-buffer-window
                     completion-reference-buffer t))))))
      (message "M: %S, REFB: %S, RFR: %S, SELFR: %S" ; @@@
               mini-win completion-reference-buffer
               redirect (selected-frame))
      (redirect-frame-focus (selected-frame) redirect))
    return-window))

> 2) I don't understand why vanilla Emacs puts the *Completions*
>    buffer in focus when it's popped into a new frame

Martin answered this question, I think.  The window mgr does
this, depending on your window mgr.  Once the frame exists,
it does not do it.  But MS Windows, for example, gives the
focus to a new frame that is displayed.

> Standalone minibuffer frames are meant to work correctly
> almost out of the box, though, right?

They should be meant to do that, yes, IMO.

> > But frames remain the poor cousin to windows in
> > Emacs.  Part of that is likely due to the fact that
> > Emacs cannot completely control the behavior of
> > frames for all window managers.  Window mgrs are
> > different, and they have ultimate control.
> 
> Yes, this seems like it's the main issue here.  But 
>still, sane frame behavior doesn't seem too far off.

Hope springs eternal. ;-)





^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2017-04-16  7:16         ` martin rudalics
@ 2017-04-17  7:44           ` Charles A. Roelli
  0 siblings, 0 replies; 26+ messages in thread
From: Charles A. Roelli @ 2017-04-17  7:44 UTC (permalink / raw)
  To: martin rudalics; +Cc: 26513

>> Really?  But selecting a completion with the mouse or with RET in the
>> *Completions* window with pop-up-frames set to nil does the same.
>
> Yes.  But I never noticed.  I could have sworn that I had to type RET
> somewhere to confirm that I really wanted to do what I picked with the
> mouse or via RET in the *Completions* buffer before.

Have you ever tried Drew's icicles library before?  If you load it from
emacs -Q and enable it with M-x icicle-mode, and type M-x global- TAB
as before, then hitting TAB "cycles" to the next completion in the
*Completions* buffer.  Cycling in this case means two things:

a) Replacing the current minibuffer input with the completion cycled to,
   and highlighting it as the active region in the minibuffer
b) Moving point in the *Completions* window to the selected completion
   and highlighting it with a special face there as well.

But the *Completions* window is never (to my knowledge) the selected
window for the user.  This would be a good model to follow (IMO): the
user can initiate completion with TAB, using it to complete, say, an
initial prefix, and then hit TAB a few more times to cycle to a chosen
candidate, all without ever leaving the minibuffer window.

>> Granted, though, it's probably not a very common thing to do.
>>
>> And also, sorry if this was not clear, but this bug is for completion
>> everywhere in Emacs, not just M-x.
>
> That's why I asked.  I now think that for most users the behavior that
> the frame is selected is quite normal (for M-x) and I rather would
> expect the *Completions* window to be selected too when it appears on
> the same frame.  The current behavior is inconsistent.

See above for a way to allow cycling candidates with TAB without the
*Completions* window having to be selected.  In other applications (say,
the bash shell), hitting TAB to complete something never prevents you
from continuing to type (as would happen in Emacs if the *Completions*
window were always selected when you initiate completion).

>> Thank you; I wasn't aware of this.  Now it makes sense why the
>> *Completions* frame gets focus.  One solution to this problem, then,
>> might be to create a separate *Completions* frame on startup and update
>> it with completions as necessary, without ever deleting/recreating it.
>> I'll see if I can write a mode or something for this.
>
> Even then it might get focus.  With a focus follows mouse policy, raising
> a frame that happens to be under the mouse pointer will usually also
> focus it (blame the window manager for that).

True, I will have to try it out and see if that's a problem.

>>> Still, why would you want to "continue typing in the minibuffer" when
>>> the desired effect of what you do is to choose and execute one of the
>>> commands shown in the *Completions* buffer?
>>
>> As explained above, it isn't necessarily the desired effect, only one
>> example.
>
> Maybe it would then make sense to discriminate the use cases of
> *Completions*: One where continuing typing in the selected window
> wouldn't make sense because one has to select an item in the
> *Completions* buffer.  In that case selecting the *Completions* window
> makes perfect sense IMHO.  And one where you usually want to continue
> typing and the *Completions* buffer is just there for later perusal.

Again, see above for Drew's approach, since it allows both use cases
easily.





^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2017-04-16 15:54     ` Drew Adams
@ 2017-04-18 17:27       ` martin rudalics
  2017-04-18 20:34       ` Charles A. Roelli
  1 sibling, 0 replies; 26+ messages in thread
From: martin rudalics @ 2017-04-18 17:27 UTC (permalink / raw)
  To: Drew Adams, charles; +Cc: 26513

 >    (let ((return-window
 >           (select-window
 >            (funcall special-display-function buf args))))

Remove that ‘select-window’ call and Bob's your uncle.

martin






^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2017-04-16 15:54     ` Drew Adams
  2017-04-18 17:27       ` martin rudalics
@ 2017-04-18 20:34       ` Charles A. Roelli
  2017-04-19  7:26         ` martin rudalics
  1 sibling, 1 reply; 26+ messages in thread
From: Charles A. Roelli @ 2017-04-18 20:34 UTC (permalink / raw)
  To: Drew Adams; +Cc: 26513

Hi Drew,

On Sun, Apr 16 2017 at 08:54:37 am, Drew Adams wrote:

>> 1) Does this still work without a standalone minibuffer frame?  I'm
>>    interested in using one, but I'd rather fix the *Completions* frame
>>    problem first before adding on a minibuffer-only frame to my setup.
>
> I can make it work without a standalone minibuffer frame
> in all Emacs versions before Emacs 25.  For some reason,
> redirecting the frame focus does not seem to work right
> for Emacs 25 when there is no standalone minibuffer frame.
> I hope I'm just missing something simple.
>
> The following code works, for example, except for Emacs 25.
> (I have Emacs 25.1-2.)  Maybe you or Martin can explain why.
> The debug `message' calls here don't tell me that anything
> is wrong, but clearly something is.
>
> I tried some variants also (no `w32-grab-focus-on-raise',
> explicitly select *Completions* frame (and even set focus
> to it temporarily), etc., to no avail.
>
> (defun foo ()
>   (interactive)
>   (add-to-list 'special-display-buffer-names
>                `("*Completions*" display-comp-fr))
>   (setq w32-grab-focus-on-raise  nil))
>
> (defun display-comp-fr (buf &optional args)
>   (let ((return-window
>          (select-window
>           (funcall special-display-function buf args))))
>     (raise-frame)
>     (message "BUF: %S, WIN: %S, FR: %S"
>              buf (get-buffer-window buf)
>              (window-frame (get-buffer-window buf)))
>     (let* ((mini-win  (active-minibuffer-window))
>            (redirect
>             (if mini-win
>                 (window-frame mini-win)
>               (and completion-reference-buffer
>                    (get-buffer-window
>                     completion-reference-buffer
>                     'visible)
>                    (not (eq (get-buffer "*Completions*")
>                             completion-reference-buffer))
>                    (window-frame
>                     (get-buffer-window
>                      completion-reference-buffer t))))))
>       (message "M: %S, REFB: %S, RFR: %S, SELFR: %S" ; @@@
>                mini-win completion-reference-buffer
>                redirect (selected-frame))
>       (redirect-frame-focus (selected-frame) redirect))
>     return-window))

Thanks for this minimal example.

It also doesn't work for me on Emacs 25 either.  Emacs 24.4 does work
fine, however.  I have no clue why... maybe redirect-frame-focus has
changed in Emacs 25?

Here is the recipe I used to check if it worked:

    emacs -Q
    load your two functions
    M-x foo
    M-x global- TAB auto

Typing "auto" resulted in a "Buffer is read-only: #<buffer
*Completions*>" error when the redirection wasn't working.  When the
redirection did work, the "auto" keyboard input was correctly sent to
the minibuffer.  I also tried Martin's suggestion of removing the
(select-window) call but that didn't get rid of the error for me.

>> 2) I don't understand why vanilla Emacs puts the *Completions*
>>    buffer in focus when it's popped into a new frame
>
> Martin answered this question, I think.  The window mgr does
> this, depending on your window mgr.  Once the frame exists,
> it does not do it.  But MS Windows, for example, gives the
> focus to a new frame that is displayed.

Yep, seems to be the case for most window managers.  I never noticed
this before.

>> > But frames remain the poor cousin to windows in
>> > Emacs.  Part of that is likely due to the fact that
>> > Emacs cannot completely control the behavior of
>> > frames for all window managers.  Window mgrs are
>> > different, and they have ultimate control.
>> 
>> Yes, this seems like it's the main issue here.  But 
>>still, sane frame behavior doesn't seem too far off.
>
> Hope springs eternal. ;-)

And that's what Emacs is built on. :D





^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2017-04-18 20:34       ` Charles A. Roelli
@ 2017-04-19  7:26         ` martin rudalics
  0 siblings, 0 replies; 26+ messages in thread
From: martin rudalics @ 2017-04-19  7:26 UTC (permalink / raw)
  To: Charles A. Roelli, Drew Adams; +Cc: 26513

 > I also tried Martin's suggestion of removing the
 > (select-window) call but that didn't get rid of the error for me.

Evaluating with emacs -Q

(add-to-list 'special-display-buffer-names '("*Completions*" foo))
(setq w32-grab-focus-on-raise  nil)

(defun foo (buffer &optional args)
   (interactive)
   (let* ((mini-win  (active-minibuffer-window))
	 (mini-frame (window-frame mini-win))
	 (window
	  (select-window
	   (funcall special-display-function buffer args)))
	 (frame (window-frame window)))
     (raise-frame frame)
     (redirect-frame-focus frame mini-frame)
     window))

and typing

C-h f set- TAB

gets me a new frame with input focus.  Evaluating with emacs -Q

(add-to-list 'special-display-buffer-names '("*Completions*" foo))
(setq w32-grab-focus-on-raise  nil)

(defun foo (buffer &optional args)
   (interactive)
   (let* ((mini-win  (active-minibuffer-window))
	 (mini-frame (window-frame mini-win))
	 (window
	  (funcall special-display-function buffer args))
	 (frame (window-frame window)))
     (raise-frame frame)
     (redirect-frame-focus frame mini-frame)
     window))

and typing

C-h f set- TAB

gets me a new frame with input focus in the old frame.

Verified with Emacs 25 and 26 under Debian GTK+ and Windows XP.

martin





^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2017-04-15  9:17 bug#26513: 25.2; pop-up-frames and *Completions* buffer Charles A. Roelli
  2017-04-15 14:50 ` martin rudalics
  2017-04-15 16:49 ` Drew Adams
@ 2022-02-15 10:37 ` Lars Ingebrigtsen
  2022-02-17 10:01   ` martin rudalics
  2 siblings, 1 reply; 26+ messages in thread
From: Lars Ingebrigtsen @ 2022-02-15 10:37 UTC (permalink / raw)
  To: Charles A. Roelli; +Cc: 26513

charles@aurox.ch (Charles A. Roelli) writes:

>>From emacs -Q:
>
> M-x set-variable RET pop-up-frames RET t RET
> M-x global- TAB
>
> The *Completions* buffer is opened in a new frame, but the cursor is in
> the frame too, so the user has to switch back to the minibuffer to
> continue typing.

This problem is still present in Emacs 29.  I guess the general solution
here would be for completion to ensure that it's gotten focus back again
after displaying the *Completions* buffer?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2022-02-15 10:37 ` Lars Ingebrigtsen
@ 2022-02-17 10:01   ` martin rudalics
  2022-02-17 13:13     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2022-02-17 16:40     ` Drew Adams
  0 siblings, 2 replies; 26+ messages in thread
From: martin rudalics @ 2022-02-17 10:01 UTC (permalink / raw)
  To: Lars Ingebrigtsen, Charles A. Roelli; +Cc: Stefan Monnier, 26513

[-- Attachment #1: Type: text/plain, Size: 826 bytes --]

 >> >From emacs -Q:
 >>
 >> M-x set-variable RET pop-up-frames RET t RET
 >> M-x global- TAB
 >>
 >> The *Completions* buffer is opened in a new frame, but the cursor is in
 >> the frame too, so the user has to switch back to the minibuffer to
 >> continue typing.
 >
 > This problem is still present in Emacs 29.  I guess the general solution
 > here would be for completion to ensure that it's gotten focus back again
 > after displaying the *Completions* buffer?

Maybe Stefan Monnier can tell us what he does in such case.

I can offer the attached, largely untested patch.  A possible
customization would then be

(customize-set-variable
  'display-buffer-alist
  '(("*Completions*"
     (display-buffer-reuse-window
      display-buffer-pop-up-frame)
     (reusable-frames . t)
     (redirect-frame-focus . t))))

martin

[-- Attachment #2: redirect-frame-focus.diff --]
[-- Type: text/x-patch, Size: 6922 bytes --]

diff --git a/lisp/window.el b/lisp/window.el
index 582600e1c6..96aa2ecc2d 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -7598,6 +7598,9 @@ display-buffer
     Possible values are nil (the selected frame), t (any live
     frame), visible (any visible frame), 0 (any visible or
     iconified frame) or an existing live frame.
+ `redirect-frame-focus' -- The value t means to redirect focus
+    from the frame used for display to the frame selected at the
+    time `display-buffer' was called (if these are different).
  `pop-up-frame-parameters' -- The value specifies an alist of
     frame parameters to give a new frame, if one is created.
  `window-height' -- The value specifies the desired height of the
@@ -7740,6 +7743,7 @@ display-buffer-use-some-frame
               (lambda (frame)
                 (and (not (eq frame (selected-frame)))
                      (get-lru-window frame)))))
+         (selected-frame (selected-frame))
          (frame (car (filtered-frame-list predicate)))
          (window
           (and frame
@@ -7749,7 +7753,10 @@ display-buffer-use-some-frame
       (prog1
           (window--display-buffer buffer window 'reuse alist)
         (unless (cdr (assq 'inhibit-switch-frame alist))
-          (window--maybe-raise-frame frame))))))
+          (window--maybe-raise-frame frame))
+        (when (and (cdr (assq 'redirect-frame-focus alist))
+                   (not (eq frame selected-frame)))
+          (redirect-frame-focus frame selected-frame))))))
 
 (defun display-buffer-same-window (buffer alist)
   "Display BUFFER in the selected window.
@@ -7817,6 +7824,7 @@ display-buffer-reuse-window
 called only by `display-buffer' or a function directly or
 indirectly called by the latter."
   (let* ((alist-entry (assq 'reusable-frames alist))
+         (selected-frame (selected-frame))
 	 (frames (cond (alist-entry (cdr alist-entry))
 		       ((if (eq pop-up-frames 'graphic-only)
 			    (display-graphic-p)
@@ -7845,7 +7853,11 @@ display-buffer-reuse-window
     (when (window-live-p window)
       (prog1 (window--display-buffer buffer window 'reuse alist)
 	(unless (cdr (assq 'inhibit-switch-frame alist))
-	  (window--maybe-raise-frame (window-frame window)))))))
+	  (window--maybe-raise-frame (window-frame window)))
+        (when (and (cdr (assq 'redirect-frame-focus alist))
+                   (not (eq (window-frame window) selected-frame)))
+          (redirect-frame-focus
+           (window-frame window) selected-frame))))))
 
 (defun display-buffer-reuse-mode-window (buffer alist)
   "Return a window based on the mode of the buffer it displays.
@@ -7918,7 +7930,11 @@ display-buffer-reuse-mode-window
         (when (window-live-p window)
           (prog1 (window--display-buffer buffer window 'reuse alist)
             (unless (cdr (assq 'inhibit-switch-frame alist))
-              (window--maybe-raise-frame (window-frame window)))))))))
+              (window--maybe-raise-frame (window-frame window)))
+            (when (and (cdr (assq 'redirect-frame-focus alist))
+                       (not (eq (window-frame window) curframe)))
+              (redirect-frame-focus
+               (window-frame window) curframe))))))))
 
 (defun display-buffer--special-action (buffer)
   "Return special display action for BUFFER, if any.
@@ -7955,6 +7971,7 @@ display-buffer-pop-up-frame
   (let* ((params (cdr (assq 'pop-up-frame-parameters alist)))
 	 (pop-up-frame-alist (append params pop-up-frame-alist))
 	 (fun pop-up-frame-function)
+         (selected-frame (selected-frame))
 	 frame window)
     (when (and fun
 	       ;; Make BUFFER current so `make-frame' will use it as the
@@ -7963,8 +7980,11 @@ display-buffer-pop-up-frame
 		 (setq frame (funcall fun)))
 	       (setq window (frame-selected-window frame)))
       (prog1 (window--display-buffer buffer window 'frame alist)
-	(unless (cdr (assq 'inhibit-switch-frame alist))
-	  (window--maybe-raise-frame frame))))))
+        (unless (cdr (assq 'inhibit-switch-frame alist))
+	  (window--maybe-raise-frame frame))
+        (when (and (cdr (assq 'redirect-frame-focus alist))
+                   (not (eq frame selected-frame)))
+          (redirect-frame-focus frame selected-frame))))))
 
 (defun display-buffer-pop-up-window (buffer alist)
   "Display BUFFER by popping up a new window.
@@ -7986,7 +8006,8 @@ display-buffer-pop-up-window
 indirectly called by the latter."
   (let ((frame (or (window--frame-usable-p (selected-frame))
 		   (window--frame-usable-p (last-nonminibuffer-frame))))
-	window)
+        (selected-frame (selected-frame))
+        window)
     (when (and (or (not (frame-parameter frame 'unsplittable))
 		   ;; If the selected frame cannot be split, look at
 		   ;; `last-nonminibuffer-frame'.
@@ -8002,7 +8023,10 @@ display-buffer-pop-up-window
 
       (prog1 (window--display-buffer buffer window 'window alist)
 	(unless (cdr (assq 'inhibit-switch-frame alist))
-	  (window--maybe-raise-frame (window-frame window)))))))
+	  (window--maybe-raise-frame (window-frame window)))
+        (when (and (cdr (assq 'redirect-frame-focus alist))
+                   (not (eq frame selected-frame)))
+          (redirect-frame-focus frame selected-frame))))))
 
 (defun display-buffer--maybe-pop-up-frame-or-window (buffer alist)
   "Try displaying BUFFER based on `pop-up-frames' or `pop-up-windows'.
@@ -8086,7 +8110,9 @@ display-buffer-in-child-frame
 
     (prog1 (window--display-buffer buffer window type alist)
       (unless (cdr (assq 'inhibit-switch-frame alist))
-	(window--maybe-raise-frame frame)))))
+	(window--maybe-raise-frame frame))
+      (when (cdr (assq 'redirect-frame-focus alist))
+        (redirect-frame-focus frame parent)))))
 
 (defun windows-sharing-edge (&optional window edge within)
   "Return list of live windows sharing the same edge with WINDOW.
@@ -8456,7 +8482,8 @@ display-buffer-use-some-window
   (let* ((not-this-window (cdr (assq 'inhibit-same-window alist)))
 	 (frame (or (window--frame-usable-p (selected-frame))
 		    (window--frame-usable-p (last-nonminibuffer-frame))))
-	 (window
+         (selected-frame (selected-frame))
+         (window
 	  ;; Reuse an existing window.
 	  (or (get-lru-window frame nil not-this-window)
 	      (let ((window (get-buffer-window buffer 'visible)))
@@ -8486,7 +8513,11 @@ display-buffer-use-some-window
 	  (window--display-buffer buffer window 'reuse alist)
 	(window--even-window-sizes window)
 	(unless (cdr (assq 'inhibit-switch-frame alist))
-	  (window--maybe-raise-frame (window-frame window)))))))
+	  (window--maybe-raise-frame (window-frame window)))
+        (when (and (cdr (assq 'redirect-frame-focus alist))
+                   (not (eq (window-frame window) selected-frame)))
+          (redirect-frame-focus
+           (window-frame window) selected-frame))))))
 
 (defun display-buffer-no-window (_buffer alist)
   "Display BUFFER in no window.

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2022-02-17 10:01   ` martin rudalics
@ 2022-02-17 13:13     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2022-02-17 16:02       ` martin rudalics
  2022-02-17 16:40     ` Drew Adams
  1 sibling, 1 reply; 26+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-02-17 13:13 UTC (permalink / raw)
  To: martin rudalics; +Cc: Lars Ingebrigtsen, Charles A. Roelli, 26513

>> This problem is still present in Emacs 29.  I guess the general solution
>> here would be for completion to ensure that it's gotten focus back again
>> after displaying the *Completions* buffer?
> Maybe Stefan Monnier can tell us what he does in such case.

I have a `display-buffer-alist` entry that does all kinds of funny
things for *Completions* ;-)

> I can offer the attached, largely untested patch.

No objection to the patch, but the amount of code duplication in it
(both in the new lines and in the surrounding code) suggests we may want
to refactor some of that code so that the options processing code is
written at a single place "once" rather than
once-per-display-buffer-function.


        Stefan






^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2022-02-17 13:13     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2022-02-17 16:02       ` martin rudalics
  2022-02-17 19:21         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 26+ messages in thread
From: martin rudalics @ 2022-02-17 16:02 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Lars Ingebrigtsen, Charles A. Roelli, 26513

 > I have a `display-buffer-alist` entry that does all kinds of funny
 > things for *Completions* ;-)

Please post it here.

 > No objection to the patch, but the amount of code duplication in it
 > (both in the new lines and in the surrounding code) suggests we may want
 > to refactor some of that code so that the options processing code is
 > written at a single place "once" rather than
 > once-per-display-buffer-function.

Agreed.  But I profoundly dislike the sole idea of abusing
'redirect-frame-focus' for fixing this kind of problems.

martin





^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: [External] : bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2022-02-17 10:01   ` martin rudalics
  2022-02-17 13:13     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2022-02-17 16:40     ` Drew Adams
  1 sibling, 0 replies; 26+ messages in thread
From: Drew Adams @ 2022-02-17 16:40 UTC (permalink / raw)
  To: martin rudalics, Lars Ingebrigtsen, Charles A. Roelli
  Cc: Stefan Monnier, 26513@debbugs.gnu.org

>>> >From emacs -Q:
>>>
>>> M-x set-variable RET pop-up-frames RET t RET
>>> M-x global- TAB
>>>
>>> The *Completions* buffer is opened in a new frame, but the cursor is in
>>> the frame too, so the user has to switch back to the minibuffer to
>>> continue typing.
>>
>> This problem is still present in Emacs 29.  I guess the general solution
>> here would be for completion to ensure that it's gotten focus back again
>> after displaying the *Completions* buffer?
> 
> Maybe Stefan Monnier can tell us what he does in such case.
> 
> I can offer the attached, largely untested patch.  A possible
> customization would then be
> 
> (customize-set-variable
>   'display-buffer-alist
>   '(("*Completions*"
>      (display-buffer-reuse-window
>       display-buffer-pop-up-frame)
>      (reusable-frames . t)
>      (redirect-frame-focus . t))))

22 years ago I reported this problem.
I fixed it for my use in this way...
 
tl;dr:

Use a standalone minibuffer frame, and a
separate frame for `*Completions*' that's
displayed with a function that does this:

(redirect-frame-focus (selected-frame)
                      1on1-minibuffer-frame)
___

In my code I do this by adding function
`1on1-display-*Completions*-frame' to
`special-display-buffer-names'.  What it does:

1. `redirect-frame-focus' to the standalone
minibuffer frame if the minibuffer is active, or
to `completion-reference-buffer' (unless it's
`*Completions*') otherwise.

2. Return the window resulting from calling the
value of `special-display-function' at the start
of `1on1-display-*Completions*-frame'.
___

It does other stuff as well, which is why it
needs, at the outset, to get the window to
return:
It optionally uses the same font family for
`*Completions*' as the frame selected when the
minibuffer was set up.  It optionally shrinks
the text in `*Completions*' by a user-defined
amount.  It optionally repositions frame
`*Completions*' to the right edge of the
display temporarily, to make both it and the
original frame more visible.
___

(`display-buffer-alist' could presumably be
used instead of special-display.  I don't use
it because special-display is simpler and it's
available also for older Emacs releases that
don't have `display-buffer-alist'.)
___

The code I use is in `oneonone.el':

https://www.emacswiki.org/emacs/download/oneonone.el

^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2022-02-17 16:02       ` martin rudalics
@ 2022-02-17 19:21         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2022-02-19  9:40           ` martin rudalics
  0 siblings, 1 reply; 26+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-02-17 19:21 UTC (permalink / raw)
  To: martin rudalics; +Cc: Lars Ingebrigtsen, Charles A. Roelli, 26513

>> I have a `display-buffer-alist` entry that does all kinds of funny
>> things for *Completions* ;-)
> Please post it here.

Sorry, top secret.

>> No objection to the patch, but the amount of code duplication in it
>> (both in the new lines and in the surrounding code) suggests we may want
>> to refactor some of that code so that the options processing code is
>> written at a single place "once" rather than
>> once-per-display-buffer-function.
> Agreed.  But I profoundly dislike the sole idea of abusing
> 'redirect-frame-focus' for fixing this kind of problems.

FWIW, my code also uses `redirect-frame-focus` but I agree it's not
a great solution.

AFAIK, this all comes down to the fact that when `display-buffer`
creates a new frame, it will all too often end up being selected by the
window manager, even though Emacs doesn't want that window to be the
selected window.

I sadly don't think we have a good answer for that problem.
I also don't think there's a good reliable way to do that in
general, currently.  I suspect what we'd need to do is wait for the new
frame to be "fully" created (not just by us but also on the window
manager side) and when that is settled we should request to focus back
to the frame that had focus before the creation.

I'm sadly not well enough versed in that kind of GUI code to know how to
do it.  And its asynchronous nature makes it worse.


        Stefan






^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2022-02-17 19:21         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2022-02-19  9:40           ` martin rudalics
  2022-02-19 12:23             ` Eli Zaretskii
                               ` (2 more replies)
  0 siblings, 3 replies; 26+ messages in thread
From: martin rudalics @ 2022-02-19  9:40 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Lars Ingebrigtsen, Charles A. Roelli, 26513

In either case
 >>> I have a `display-buffer-alist` entry that does all kinds of funny
 >>> things for *Completions* ;-)
 >> Please post it here.
 >
 > Sorry, top secret.

Maybe we really should recommend Drew's package for people setting
'pop-up-frames' to t then.  Or does anyone else put *Completions* into a
separate frame?

 > FWIW, my code also uses `redirect-frame-focus` but I agree it's not
 > a great solution.

It's counter-intuitive in the OP's scenario since the *Completions*
frame has its own minibuffer window where the dialogue could be
continued as soon as that frame gets selected.  But here the minibuffer
window is not selected.  We provide hundreds sorts of completions and
I've never been able to understand even one of them.

 > AFAIK, this all comes down to the fact that when `display-buffer`
 > creates a new frame, it will all too often end up being selected by the
 > window manager, even though Emacs doesn't want that window to be the
 > selected window.
 >
 > I sadly don't think we have a good answer for that problem.
 > I also don't think there's a good reliable way to do that in
 > general, currently.  I suspect what we'd need to do is wait for the new
 > frame to be "fully" created (not just by us but also on the window
 > manager side) and when that is settled we should request to focus back
 > to the frame that had focus before the creation.
 >
 > I'm sadly not well enough versed in that kind of GUI code to know how to
 > do it.  And its asynchronous nature makes it worse.

Our present weaponry for dealing with this ('no-focus-on-map' or even
'no-accept-focus') is apparently inadequate or was never even tested.
The only thing I recall is that waiting for the new frame to get
reported (on X it's even never clear which event is responsible for
that) and deselecting it afterwards leads to some sort of flickering.

martin





^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2022-02-19  9:40           ` martin rudalics
@ 2022-02-19 12:23             ` Eli Zaretskii
  2022-02-20  0:25               ` bug#26513: [External] : " Drew Adams
  2022-02-20  0:28             ` Drew Adams
  2022-02-21 16:25             ` Drew Adams
  2 siblings, 1 reply; 26+ messages in thread
From: Eli Zaretskii @ 2022-02-19 12:23 UTC (permalink / raw)
  To: martin rudalics; +Cc: larsi, charles, monnier, 26513

> Date: Sat, 19 Feb 2022 10:40:33 +0100
> From: martin rudalics <rudalics@gmx.at>
> Cc: Lars Ingebrigtsen <larsi@gnus.org>, "Charles A. Roelli" <charles@aurox.ch>,
>  26513@debbugs.gnu.org
> 
> In either case
>  >>> I have a `display-buffer-alist` entry that does all kinds of funny
>  >>> things for *Completions* ;-)
>  >> Please post it here.
>  >
>  > Sorry, top secret.
> 
> Maybe we really should recommend Drew's package for people setting
> 'pop-up-frames' to t then.

Didn't Drew say at some point that breaks Emacs 27 and later?





^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: [External] : bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2022-02-19 12:23             ` Eli Zaretskii
@ 2022-02-20  0:25               ` Drew Adams
  0 siblings, 0 replies; 26+ messages in thread
From: Drew Adams @ 2022-02-20  0:25 UTC (permalink / raw)
  To: Eli Zaretskii, martin rudalics
  Cc: larsi@gnus.org, charles@aurox.ch, monnier@iro.umontreal.ca,
	26513@debbugs.gnu.org

> > In either case
> >  >>> I have a `display-buffer-alist` entry that does all kinds of funny
> >  >>> things for *Completions* ;-)
> >  >> Please post it here.
> >  >
> >  > Sorry, top secret.
> >
> > Maybe we really should recommend Drew's package for people setting
> > 'pop-up-frames' to t then.
> 
> Didn't Drew say at some point that breaks Emacs 27 and later?

1. I don't recommend generally recommending to
   use my code for this.  See my reply to Martin.

2. What I said wrt Emacs 27+ is that Emacs 27+
   breaks use of my setup (not the other way
   around).  In particular, although I manage
   which frame gets the focus, that control
   apparently gets overridden by something in
   Emacs 27+.

   (I think Stefan mentioned something similar,
   but he said it started with Emacs 26 (?), and
   I too have some problems that were introduced
   in Emacs 26.)

   Icicles allows use of a minibuffer along with
   with changing selected window and focused
   frame during minibuffer input (including with
   recursive minibuffers).  E.g., you can switch
   among windows and do things there while the
   minibuffer waits for input.  This requires
   control by the particular commands involved
   (commands that read from the minibuffer but
   also commands bound to minibuffer keys that
   result in interactions in other windows).







^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: [External] : bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2022-02-19  9:40           ` martin rudalics
  2022-02-19 12:23             ` Eli Zaretskii
@ 2022-02-20  0:28             ` Drew Adams
  2022-02-20  9:17               ` martin rudalics
  2022-02-21 16:25             ` Drew Adams
  2 siblings, 1 reply; 26+ messages in thread
From: Drew Adams @ 2022-02-20  0:28 UTC (permalink / raw)
  To: martin rudalics, Stefan Monnier
  Cc: Lars Ingebrigtsen, Charles A. Roelli, 26513@debbugs.gnu.org

> In either case
>  >>> I have a `display-buffer-alist` entry that does all kinds of funny
>  >>> things for *Completions* ;-)
>  >> Please post it here.
>  >
>  > Sorry, top secret.
> 
> Maybe we really should recommend Drew's package for people setting
> 'pop-up-frames' to t then.  Or does anyone else put *Completions* into a
> separate frame?

tl;dr: No, please don't.
___

No, I don't recommend that.  I try to keep it working
across Emacs releases, but it's not to be depended on.

In addition, for real reasonable behavior wrt frame
focusing etc. I find using Icicles with it to be
almost a necessity.

I mentioned it only FWIW, to suggest maybe a way to
approach the problem (redirect the frame focus from
a dedicated *Completions* frame to a standalone
minibuffer frame).

The problem is a general one, and twofold, IMO:

1. Window managers, not Emacs itself, have ultimate
control over the behavior of frames.

2. Most Emacs users, including most Emacs developers,
use Emacs windows for most buffers.  They don't try
to use separate frames in general.  As a result (IMO),
the behavior of frames in Emacs gets much less love
than the behavior of windows (placement etc.).

This situation is a given, I'm afraid.  And it's
understandable.

Back in the early 90s there was an Emacs called
Epoch.  It had (by default, IIRC) a standalone
minibuffer frame, and for most things (IIRC) it
used what GNU Emacs calls frames.  And it just
worked.  Since that's the way it was defined -
the default, that's what got maintained, developed,
etc.

When I changed to use GNU Emacs again I tried to
reproduce a setup like that of Epoch.  I found
many hurdles and hoops, and I only partially have
been able to jump over and through most of them.

Long ago I wrote some on this, here (including
the linked pages):

https://www.emacswiki.org/emacs/OneOnOneEmacs

>  > FWIW, my code also uses `redirect-frame-focus` but I agree it's not
>  > a great solution.
> 
> It's counter-intuitive in the OP's scenario since the *Completions*
> frame has its own minibuffer window where the dialogue could be
> continued as soon as that frame gets selected.  But here the minibuffer
> window is not selected.  We provide hundreds sorts of completions and
> I've never been able to understand even one of them.

I sympathize.  Yeah, it's a jungle out there.

> Our present weaponry for dealing with this ('no-focus-on-map' or even
> 'no-accept-focus') is apparently inadequate or was never even tested.
> The only thing I recall is that waiting for the new frame to get
> reported (on X it's even never clear which event is responsible for
> that) and deselecting it afterwards leads to some sort of flickering.

(I'm not familiar with `no-accept-focus' and
`no-focus-on-map'.  I see them now, in
(elisp) `Management Parameters'.)

Wrt frame focus problems stemming from some
window mgrs focusing a new frame etc.: I wonder
whether it might help (in the case of dedicated
frames) to pre-create the relevant frames such
as *Completions*, and instead of deleting them
and re-creating them, make them invisible and
show them again.

Dunno.  I don't recall whether I ever tried
such an approach.  And maybe we'd run into
problems from different window mgrs handling
visibility of frames in different (odd) ways.
(See problem #1, above.)

^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: [External] : bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2022-02-20  0:28             ` Drew Adams
@ 2022-02-20  9:17               ` martin rudalics
  2022-02-20 21:16                 ` Drew Adams
  0 siblings, 1 reply; 26+ messages in thread
From: martin rudalics @ 2022-02-20  9:17 UTC (permalink / raw)
  To: Drew Adams, Stefan Monnier
  Cc: Lars Ingebrigtsen, Charles A. Roelli, 26513@debbugs.gnu.org

 > Wrt frame focus problems stemming from some
 > window mgrs focusing a new frame etc.: I wonder
 > whether it might help (in the case of dedicated
 > frames) to pre-create the relevant frames such
 > as *Completions*, and instead of deleting them
 > and re-creating them, make them invisible and
 > show them again.

It might be worth pursuing such an approach.  Provided we can convince a
sufficiently large number of WMs to not auto-focus a frame when making
it visible.

martin





^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: [External] : bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2022-02-20  9:17               ` martin rudalics
@ 2022-02-20 21:16                 ` Drew Adams
  0 siblings, 0 replies; 26+ messages in thread
From: Drew Adams @ 2022-02-20 21:16 UTC (permalink / raw)
  To: martin rudalics, Stefan Monnier
  Cc: Lars Ingebrigtsen, Charles A. Roelli, 26513@debbugs.gnu.org

>  > Wrt frame focus problems stemming from some
>  > window mgrs focusing a new frame etc.: I wonder
>  > whether it might help (in the case of dedicated
>  > frames) to pre-create the relevant frames such
>  > as *Completions*, and instead of deleting them
>  > and re-creating them, make them invisible and
>  > show them again.
> 
> It might be worth pursuing such an approach.  Provided we can convince a
> sufficiently large number of WMs to not auto-focus a frame when making
> it visible.

;-)

(I didn't realize that they do that.)

^ permalink raw reply	[flat|nested] 26+ messages in thread

* bug#26513: [External] : bug#26513: 25.2; pop-up-frames and *Completions* buffer
  2022-02-19  9:40           ` martin rudalics
  2022-02-19 12:23             ` Eli Zaretskii
  2022-02-20  0:28             ` Drew Adams
@ 2022-02-21 16:25             ` Drew Adams
  2 siblings, 0 replies; 26+ messages in thread
From: Drew Adams @ 2022-02-21 16:25 UTC (permalink / raw)
  To: martin rudalics, Stefan Monnier
  Cc: Lars Ingebrigtsen, Charles A. Roelli, 26513@debbugs.gnu.org

>>> I have a `display-buffer-alist` entry that does
>>> all kinds of funny things for *Completions* ;-)
>> Please post it here.
>
> Sorry, top secret.

How about declassifying it and sharing it?
What do you have to lose?  Funny things can be fun.  


^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2022-02-21 16:25 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-15  9:17 bug#26513: 25.2; pop-up-frames and *Completions* buffer Charles A. Roelli
2017-04-15 14:50 ` martin rudalics
2017-04-15 19:14   ` Charles A. Roelli
2017-04-15 19:40     ` martin rudalics
2017-04-15 20:28       ` Charles A. Roelli
2017-04-16  7:16         ` martin rudalics
2017-04-17  7:44           ` Charles A. Roelli
2017-04-15 16:49 ` Drew Adams
2017-04-15 20:05   ` Charles A. Roelli
2017-04-16 15:54     ` Drew Adams
2017-04-18 17:27       ` martin rudalics
2017-04-18 20:34       ` Charles A. Roelli
2017-04-19  7:26         ` martin rudalics
2022-02-15 10:37 ` Lars Ingebrigtsen
2022-02-17 10:01   ` martin rudalics
2022-02-17 13:13     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-02-17 16:02       ` martin rudalics
2022-02-17 19:21         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-02-19  9:40           ` martin rudalics
2022-02-19 12:23             ` Eli Zaretskii
2022-02-20  0:25               ` bug#26513: [External] : " Drew Adams
2022-02-20  0:28             ` Drew Adams
2022-02-20  9:17               ` martin rudalics
2022-02-20 21:16                 ` Drew Adams
2022-02-21 16:25             ` Drew Adams
2022-02-17 16:40     ` Drew Adams

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).