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

From: martin rudalics <[email-masked]>
Date: Tue, 12 Jul 2022 09:35:00 +0200

> That's not a fact.  I typically run with several/many frames on my tty.
 > Six, or even nine, is not uncommon.  I switch between them using the
 > <Fn> keys.  The minibuffer not staying in "its own" frame was annoying
 > me quite a bit.

This at least explains why you never experience focus problems with your
setup.

 >> I have no experience with running GDB from anywhere but Emacs itself.
 >> IIRC Linux ttys are full-screen, so where would my Emacs frames fit in?
 >
 > The GDB Emacs is on a tty, in a single frame.  The frames of the target
 > Emacs can be on X Windows.  (Or in another tty.)  So you would start the
 > target Emacs in X, note its process-id with ps a, start  gdb in the tty
 > Emacs, then do attach <proc-id>, and carry on as usual.  When you reach
 > a breakpoint, the X session appears to hang, at which point you type
 > <ctrl>-<alt>-<F4> (for example) to get to the Emacs and GDB.  When you
 > type continue in GDB, you then return to X with (e.g.) <alt>-<F7>.  It's
 > not as cumbersome as it sounds.

Thanks.  I will try that.

 > Apologies: the doc string for select-window virtually says it grabs the
 > focus.  Couldn't we go the whole way, and explicitly state that
 > select-window is really "select-window-set-input-focus"?

But we can't guarantee that.  Popping up a new frame via 'pop-to-buffer'
should do that via 'select-frame-set-input-focus'.  But if the window
manager forbids focus stealing, it doesn't.  The new frame may even come
up totally obscured.

 >> The Elisp manual is controversial about this.  A sentence like
 >
 >>     Note that sometimes selecting a window is not enough to show it, or
 >>     make its frame the top-most frame on display: you may also need to
 >>     raise the frame or make sure input focus is directed to that frame.
 >
 > That sounds like the text from a bug report.  Selecting a window should
 > either do all these GUI things, or it shouldn't do them.  "Sometimes"
 > feels like an apology for failing to fix a bug before a release.

The text mirrors the savage wilderness of GUIs - eat and be eaten.
That's not the clean, well-lighted environment of a tty.

 > So why can't we make select-window _always_ raise its frame and get
 > input focus?  Perhaps we would also need a (new) function which would
 > just make the struct window * current for manipulation without it being
 > displayed on the screen.
 >
 > That would give us two unambiguously distinct functions for windows, in
 > the same way we have (ought to have) select-frame-set-input-focus and
 > select-frame for frames.  Here I advocate amending select-frame such
 > that it _never_ grabs the focus.  (Assuming I haven't done that already
 > with that 53-line patch.)

'display-buffer', for example, should not select the window it uses.
But if you display the buffer in a new frame and the window manager
decides to always give focus to a new frame, that window will be
selected.  It took me years to convince Drew that Emacs can't do
anything about that.

It would help if we had APIs that left the choice whether a new frame
should receive focus or be raised to the application.  I've never seen
one that does that.  (Rightfully so - think of applications that within
milliseconds ask for moving focus from one window to another and back.)

 >>   > 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).
 >
 >> Indeed.  Which means that it contradicts the Elisp manual which says
 >> about 'select-window' that
 >
 >>     This function makes WINDOW the selected window and the window
 >>     selected within its frame, and selects that frame.
 >
 > Yes.  :-(  But that (normal) frame _is_ selected.  It's just that its
 > focus has been redirected to the minibuffer frame.  Normally, C-x o
 > doesn't move the focus away from the currently focussed frame.
 >
 >> and about the window “selected within the frame”
 >
 >>     For the selected frame, that window is
 >>     called the “selected window”—the one in which most editing takes place,
 >>     and in which the cursor for selected windows appears
 >
 >> Here the cursor for the selected window appears in the minibuffer frame
 >> window and that's what fooled me.  In which window should the cursor
 >> appear in your opinion?
 >
 > In the focussed frame, in the selected window in it.  That would be in
 > the minibuffer window, surely?

But that's not the selected window which is, according to what you say
above, the selected window of the normal frame.

 > I don't think the documentation in the Elisp manual quite covers
 > complexities like MB-only frames and focus redirection.  Surely C-x o
 > shouldn't move the focus to a different frame?

When the minibuffer is active it should (even if it does not succeed in
all cases) because 'other-window' calls 'select-window'.

 > Surely C-x o shouldn't move the focus to a different frame?

It did so ever since the code you elided was written.

 > Here the
 > user would have C-x 5 o to move to that normal frame.  Any user chosing
 > a minibuffer-only frame setup (for whatever advantages) should be aware
 > of things like that.

This is not only about minibuffer-only frame setups.  It can happen
whenever a frame without minibuffer is made.  The underlying idea is
that navigation within the cyclic ordering of windows should be coherent
regardless of where the minibuffer window resides.

 > That's a terrible piece of writing.  The "using" could mean either of
 > "switch between all the frames which use that MB frame" or "switch
 > between all the frames by using the minibuffer frame as a mechanism".
 >
 > I still can't make sense out of that comment.  But the code it was
 > attached to caused the new frame to grab the focus, and that was what
 > happened in the bug scenario.  In fact there, the redirection of the new
 > frame (the normal frame) was left pointing at itself.

You're barking at the wrong tree.  That code worked well for half of its
lifetime.  What really got us into the present bredouille was commit
6355802033d202c63f6fff4b77bf2b0c7aecceef and its ill-fated decision to
call Fselect_window instead of directly setting selected frame and
window as the well-established and tested code in display_mode_lines
did and still does.

In the sequel, obscure bugs began to pile up, all very difficult to
describe and reproduce (Bug#23124, Bug#24285, Bug#34317) and were fixed
with some trickery.  The origin of all that evil remained in place.
Making the minibuffer follow the selected frame was just the final stab.

 >> If we were to change that, we would change the entire cyclic ordering
 >> of windows concept which explicitly states that "If the minibuffer is
 >> active, the minibuffer window is included too" and that window may
 >> reside on any frame.
 >
 > If we change all this (and I think we should), we should do it in a way
 > which doesn't disturb the cyclic ordering.

We should eliminate the original sin and be done with it once and for all.

martin