Subject: bug#56305: 29.0.50; 'yes-or-no-p' deselects minibuffer frame

From: Alan Mackenzie <[email-masked]>
Date: Sun, 10 Jul 2022 11:34:50 +0000

Hello, Martin.

On Sun, Jul 10, 2022 at 10:07:28 +0200, martin rudalics wrote:
>  > diff --git a/src/minibuf.c b/src/minibuf.c
>  > index 0fc7f2caa1..0d80b2ec90 100644
>  > --- a/src/minibuf.c
>  > +++ b/src/minibuf.c
>  > @@ -896,6 +896,16 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
>  >     /* Don't allow the user to undo past this point.  */
>  >     bset_undo_list (current_buffer, Qnil);

>  > +  /* If some Emacs frame currently has the window-system focus, give
>  > +     it to the minibuffer frame.  This is sometimes needed for
>  > +     minibuffer-only frames.  Don't give that frame the focus if it's
>  > +     already got it, since this might cause the frame to be wrongly
>  > +     raised.  */
>  > +  if (FRAME_DISPLAY_INFO (XFRAME (mini_frame))->x_focus_frame
>  > +      && (FRAME_DISPLAY_INFO (XFRAME (mini_frame))->x_focus_frame
>  > +	  != XFRAME (mini_frame)))
>  > +    Fx_focus_frame (mini_frame, Qt);
>  > +
>  >     recursive_edit_1 ();

>  >     /* If cursor is on the minibuffer line,

>  > How do you react to this suggestion?  Anyhow, I just tried it on a Linux
>  > tty, and it segfaults.  ;-(  So it clearly needs some refinement.

> This doesn't improve anything here.  On Debian I'm using a setup which
> is described under "Focus Settings" here

> https://docs.xfce.org/xfce/xfwm4/4.12/preferences

Thanks!  I use xfce, too.  But I haven't changed anything here away from
its default.  I run Emacs on a tty anyway.

> In particular, I (a) Automatically raise windows when they receive focus
> and I use a (b) Delay before raising focused window.  (a) is for me
> indispensable to bring a window to foreground with the mouse (mainly due
> to a habit developed while working under Windows where clicking into a
> lowered frame to raise it inevitably moved point in the Emacs window
> clicked at).  (b) is indispensable to avoid that some arbitrary window
> gets raised when moving the mouse over it while trying to reach some
> specific window (this is one case mutter handles decidedly better than
> xfwm).  If anybody can suggest a better setup for emulating what Emacs
> calls 'mouse-autoselect-window' on the display level, I'll be all ears.

> Now note that when in my scenario I type C-x C-c, the minibuffer frame
> is selected and has focus.

But not raised, though?  Surely the MB frame being selected and having
focus is what we want, so that we can type "yes" or "no" next.

> Then apparently the

> Fselect_window (old_window, Qt)

> call in unwind_format_mode_line (the one you mentioned earlier in this
> thread) kicks in causing the window manager to move focus to the normal
> frame.

(See below.)

> Finally, your patch will ask the window manager to focus the
> minibuffer frame again and raise it.

> I used the term "apparently" because there are too many do_switch_frame
> calls triggered by redisplay in order to attribute them orderly to their
> precise origin.  And tracing focus transitions with GDB is next to
> impossible because you continuously have to shift focus between GDB and
> the debugged application.

Try running GDB in an Emacs on a Linux tty.  That's what I do anyway.  I
seem to remember watching the focus, last time I did this, a day or two
ago.

Anyway, we'll have to decide soon what to do for Emacs 28.2.  The first
pretest is already out there.  What we do needs to be simple and safe.
The alternatives so far seem to be do nothing, apply the 53-line
deletion from master (which Eli has already rejected) or apply my patch
above (fixed to work with tty's).  At the moment, I would favour the
last of these.

> Nota bene: In each redisplay cycle, Emacs may ask the window manager at
> least twice for each of its frames to refocus it in order to format that
> frame's title.  Doesn't a window manager have better things to do than
> cater for how applications try to format their internal data?  Doesn't
> such an interaction strike anyone as provocative at least?

select-window and select-frame should NOT move the focus.  select-frame
is even documented (in the Elisp manual) not to do this.  That
documentation is not true for Emacs 28.x, but may now have become true
in master since I removed those 53 lines from do_switch_frame, but I'm
not sure.

A worthwhile project would be rigourously to determine where the focus
gets changed as a side effect of other things and to remove such side
effects.  Then we could add code to move the focus when we actually want
to.

>  > I suggested using s-f-s-input-focus at one time, but you pointed out
>  > that this would raise the frame, which isn't wanted.

> s-f-s-input-focus would add insult to injury - guaranteeing an unwanted
> raise even if 'x-focus-frame' alone would not raise it.

>  > But surely every window manager will give the minibuffer frame the
>  > focus, precisely what we need here?

> I wouldn't even bet on that.  Certainly not with newer generations of
> window managers.  A WM may concede input focus upon an application's
> request for special windows like dialog boxes only.  We're just lucky if
> it allows to give focus to some "normal" window too.

You're implying that C-x 5 o might not work with such WMs.  That would
not be good.

>  > What could happen with a strange WM
>  > that could be disturbing?

> Isn't that the wrong question?  Here we talk about a strange application
> that within milliseconds asks the WM to move focus away from one of its
> windows and then move it back to the original window in order to format
> its internal data.

As I said, I don't think select-frame/window should move the focus.
Maybe somebody could fix this for Emacs 29.

>  >> The change to master fixes the bug here.

>  > Thanks!

> Unfortunately, it breaks C-x o.  Try with my scenario but instead of
> answering the 'yes-or-no-p' question type C-x o.  With Emacs 28.1 this
> selects the window on top of the normal frame.  With current master it
> does nothing.

I don't think that's true.  It selects the other window on the normal
frame (which is the selected frame), but retains the focus in the
minibuffer frame (the focus being redirected from the normal frame).

> It doesn't even tell me that there is no other window to select.  So
> this cure is certainly worse than the disease.

I think that might be over-stating things.  Most of the time, users are
just going to be typing "yes" or "no" here.

> martin

-- 
Alan Mackenzie (Nuremberg, Germany).