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

From: martin rudalics <[email-masked]>
Date: Sun, 10 Jul 2022 10:07:28 +0200

> 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

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

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?

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

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

 >> 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.  It doesn't even tell me that there is no other window to
select.  So this cure is certainly worse than the disease.

martin