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

From: Alan Mackenzie <[email-masked]>
Date: Sat, 2 Jul 2022 11:38:06 +0000

Hello, Eli and Martin.

On Wed, Jun 29, 2022 at 22:10:49 +0300, Eli Zaretskii wrote:
> > Date: Wed, 29 Jun 2022 19:54:44 +0200
> > From: martin rudalics <[email-masked]>

> > With emacs -Q --load "~/mini.el" which contains the three lines

> > (setq use-dialog-box nil)
> > (setq default-frame-alist '((minibuffer . nil)))
> > (shell)

> > and type C-x C-c in the minibuffer frame.  This asks a 'yes-or-no-p'
> > question in the minibuffer frame but selects the *Process List* window
> > on the other frame.

> > FWICT this worked correctly until Emacs 26, was broken in Emacs 27,
> > returned to work in Emacs 28.1 and is now broken on both, release and
> > master branch, again.

> Alan, could you please look into this?  Emacs 28.2 is about to start
> pretest.

At the point in read_minibuf where recursive_edit_1 is called, all the
frame and window variables appear to be in order - things like
minibuf_window, current_buffer, selected_window, selected_frame, ...

What is not in order is the window system focus, which in the bug
scenario is on the "normal" frame rather than the minibuffer frame.  As a
matter of interest, if the C-x C-c command is invoked from the "normal"
frame, things work correctly.

As a matter of interest, when I moved from the "normal" frame to the
minibuffer frame with <alt><tab> (or clicking on the MB frame), there
wasn't the expected call to do_switch_frame ().

I don't understand why the current bug is happening; focus switching in
Emacs is complicated.  However, the following patch is, at least, a
workaround for the problem.  Should I commit it?

diff --git a/src/minibuf.c b/src/minibuf.c
index 0fc7f2caa1..5480d1f2af 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -896,6 +896,10 @@ 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);
 
+  /* Ensure that the minibuffer frame has the window-system focus.
+     This is sometimes needed for minibuffer-only frames.  */
+  call2 (Qselect_frame_set_input_focus, mini_frame, Qt);
+
   recursive_edit_1 ();
 
   /* If cursor is on the minibuffer line,

> Thanks.

-- 
Alan Mackenzie (Nuremberg, Germany).