emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Stop frames stealing eachothers' minibuffers!


From: martin rudalics
Subject: Re: Stop frames stealing eachothers' minibuffers!
Date: Sat, 21 Nov 2020 10:02:15 +0100

>> (setq default-frame-alist '((minibuffer . nil)))
>
>> (defun foo ()
>>     (interactive)
>>     (read-from-minibuffer "...?")
>>     (insert (format "%s" (selected-frame))))
>
>> insert (foo) into *scratch* and type C-x C-e.  After answering the
>> prompt this gets me #<frame *Minibuf-1* 0x36132d8>.  Do the same with
>> Emacs 27 and it will get you the *scratch* frame.
>
> Yes, I see this (except for the Emacs 27 bit which I haven't tried,
> yet).
>
> However, if I type (frame-list) into *scratch* and do C-x C-e I get only
> one frame in the list, and it has the same address in the #<frame ...>
> output as the " *Minibuf-1* 0xxxx" output.

You have to _load_ the

(setq default-frame-alist '((minibuffer . nil)))

part, it won't work after your default initial frame has been already
set up.  Run Emacs via something like

emacs -Q --load ~/foo.el

to see the effect (and please try to get used to test any changes in
this area with such a setup as well).

But indeed, with Emacs -Q executing 'foo' defined as

(defun foo ()
  (interactive)
  (read-from-minibuffer "...?")
  (insert (format "window: %s .. frame: %s" (selected-window) 
(selected-frame))))

reveals another aspect broken by your change.  The values reported by
'selected-window' and 'select-frame' do not match up any more (unless
our masochistic way or printing frame names hides an important detail).

> In other words, I think your (insert (format "%s" (selected-frame))) is
> getting the correct frame, but the current buffer within it is still the
> minibuffer.

The frame is _not_ correct - try with a separate minibuffer frame.

> Might you possibly have simplified the recipe so much that the problem
> is no longer shown by the recipe?  Removing the setting of
> default-frame-alist from the file doesn't seem to make any difference.

See above.

> Why were we selecting a frame as an "incidental" side effect of restoring
> a window configuration?  Surely the frame to be selected should be
> selected deliberately and explicitly.

Agreed.  But I suppose the current behavior was chosen precisely to
support the use case we're discussing here: With a separate minibuffer
frame it has to restore the frame that was selected before the
minibuffer interaction started.  All the remaining stuff done by
restore_window_configuration is rubbish IMHO.  Basically, minibuffer
only frames could work seamlessly were it not for the complications that
people added over the years:

'restore_window_configuration': Anything the minibuffer dialogue changes
in the window configuration of a normal frame (like popping up
completions) should be undone immediately by the associated code.  Any
changes to the configuration done explicitly by the user in between
(like, for example, splitting a window to run some other application in
it) should not be undone.

'redirect-frame-focus': There's should be no need for that - when the
minibuffer becomes active, raise its frame to send keystrokes to it.
With the above minibuffer nil setting here I get a minibuffer frame that
is hidden by the non-minibuffer frame when it shows the prompt - no
wonder that people immediately refrain from using such a set up.  The
prompt must be initially visible - always and everywhere.  Emacs should
be no hide-and-seek game.

'frame-auto-hide-function': No need for that either.  When a minibuffer
frame becomes active, it should become visible and be displayed on top
of the frame from where the dialogue originated.  When the dialogue
terminates, the minibuffer frame should return to its prior state.

Obviously, people might dislike a minibuffer-only frame getting focus
every time something is displayed in the echo area.  But that's just a
consequence of Emacs habit to conflate minibuffer and echo area in one
and the same part of a user's display.

> I'm thinking that what needs restoring is the frame's current buffer, and
> I'm wondering why that wasn't done by the (set-window-configuration foo
> t) which happened near the end of read_minibuf.

A frame does not have a current buffer.  The "current buffer" is a
completely different concept.  The only real connection is that in
keyboard.c the

      set_buffer_internal (XBUFFER (XWINDOW (selected_window)->contents));

resets the current buffer to that of the selected window which also
should be the selected frame's selected window.  But your change
apparently broke that.

martin



reply via email to

[Prev in Thread] Current Thread [Next in Thread]