Subject: bug#48674: Frames and minibuffer bug

From: Alan Mackenzie <[email-masked]>
Date: Fri, 28 May 2021 17:15:37 +0000

Hello, Martin.

On Fri, May 28, 2021 at 10:26:32 +0200, martin rudalics wrote:
>  >> Does this mean that the

>  >>     Fselect_window (f->selected_window, norecord);

>  >> in do_switch_frame fails?  If so, why?

>  > For some values of "fails", yes.  When we're in frame F1's minibuffer,
>  > and do (with-selected-frame F2 (foo)):
>  > (i) Frame F2 becomes selected.
>  > (ii) The current window in F1 ceases to be the mini-window, becoming some
>  > other window.
>  > (iii) The minibuffer is moved from F1 to F2.

>  > (iv) We evaluate (foo).

>  > (v) Frame F1 becomes selected again.
>  > (vi) The current window in F1 doesn't revert to being the mini-window.

> But why precisely does Fselect_window fail here?

Sorry, my last night's reply wasn't very clear.  That Fselect_window in
do_switch_frame will fail when a later Fselect_window (or more precisely,
Fset_frame_selected_window) in move_minibuffers_onto_frame selects a
different window for that frame.  That happens when with-selected-frame
selects a different frame, moving the minibuffers onto that other frame.

I have another idea for solving this problem.  Suppose when we switch
from F1 to F2, and F1's selected window is the mini-window, we allow F1
to remain in the MW.  The minibuffer stack gets moved to F2.  Some sort
of commands or Lisp runs in F2, then we return to F1.  Should any
minibuffer come back to F1, we allow the MW to remain selected.
Otherwise we select a different window in F1.

I think this would work better that what I proposed last night.  I'll try
and formulate a patch for this this evening.

>  > This is what has preoccupied me over the last few hours.  It seems
>  > we want do_switch_frame to do different things for (i) a "permanent"
>  > frame switch (e.g. C-x 5 o) and (i) a "temporary" frame switch (e.g.
>  > with-selected-frame).  If the selected window in F1 is the
>  > mini-window, we want it to select a different window in (i), but
>  > stay the same in (ii).

> Be careful in one additional regard: The display engine calls
> Fselect_window too for its own purposes.

.... and Fselect_window calls Fselect_frame, if needed.  This hits the
same problem.

>  >> Are we sure that we want to disallow a function on
>  >> `minibuffer-setup-hook' to change the selected window?  With Emacs 27

>  >> (defun foo ()
>  >>     (select-window (frame-first-window)))

>  >> (add-hook 'minibuffer-setup-hook 'foo)

>  >> works without any problems here.

>  > Are you sure?  For me, that setup makes C-x C-f open a minibuffer,
>  > but leave point in the same window, not the miniwindow.  That was a
>  > quick try with the emacs-27 branch, not Emacs 27.{1,2}, and was on a
>  > GUI.

> Yes.  But this is an effect the user/application might want - explicitly
> select some other window to, for example (I'm purely speculating), select
> a completion window right away.  Iris OTOH never wants to select another
> window explicitly.

OK.

>  > I think we should disallow selecting windows in minibuffer-setup-hook.
>  > This hook is run after the mini-window has been selected in read_minibuf,
>  > just before the recursive edit.

> We cannot disallow it.  We can only undo its effect.  And that would
> constitute an incompatible change - do you really want to go for it?

Maybe not.  I'm going to write a patch as outlined above, which might
well be easier to follow than my text above.  I think it might well fix
the bug properly.

> martin

-- 
Alan Mackenzie (Nuremberg, Germany).