emacs-devel
[Top][All Lists]
Advanced

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

Stop frames stealing eachothers' minibuffers!


From: Alan Mackenzie
Subject: Stop frames stealing eachothers' minibuffers!
Date: Tue, 13 Oct 2020 19:02:55 +0000

Hello, Emacs.

In recent versions of master (and, I believe the emacs-27 branch) frames
steal eachothers' minibuffers.

By this I mean:
(i) Have two frames open displaying buffers.
(ii) On frame F1 do C-x b.  This leaves a minibuffer open there.
(iii) Move to F2.
(iv) Do C-x 8 RET <enter some character>.

F1's minibuffer is now on F2.  This is bad.

Seeing as how a minibuffer often has a strong association with its frame
(e.g., C-x C-f opens a buffer in the same frame it was invoked from),
this shifting of minibuffers from one frame to another is confusing.

The following patch is a first attempt at fixing this.  Note that it
adds no code, it merely takes away code which was hindering the desired
operation, and simplifies minibuf.c appreciably.  I might well have
missed subtle points in this proposed change.

It has also changed (?improved) the error handling behaviour somewhat.
In the above scenario, after applying the patch:
(v) in F2 do M-x.

This errors with "Command attempted to use minibuffer while in
minibuffer", yet no longers aborts the command which has opened the
(first) minibuffer.  Personally, I think this is less confusing and
potentially less annoying than the current behaviour.

Comments?



diff --git a/src/minibuf.c b/src/minibuf.c
index f957b2ae17..10e58cc86b 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -76,37 +76,13 @@ choose_minibuf_frame (void)
       && !EQ (minibuf_window, XFRAME (selected_frame)->minibuffer_window))
     {
       struct frame *sf = XFRAME (selected_frame);
-      Lisp_Object buffer;
-
       /* I don't think that any frames may validly have a null minibuffer
         window anymore.  */
       if (NILP (sf->minibuffer_window))
        emacs_abort ();
 
-      /* Under X, we come here with minibuf_window being the
-        minibuffer window of the unused termcap window created in
-        init_window_once.  That window doesn't have a buffer.  */
-      buffer = XWINDOW (minibuf_window)->contents;
-      if (BUFFERP (buffer))
-       /* Use set_window_buffer instead of Fset_window_buffer (see
-          discussion of bug#11984, bug#12025, bug#12026).  */
-       set_window_buffer (sf->minibuffer_window, buffer, 0, 0);
       minibuf_window = sf->minibuffer_window;
     }
-
-  /* Make sure no other frame has a minibuffer as its selected window,
-     because the text would not be displayed in it, and that would be
-     confusing.  Only allow the selected frame to do this,
-     and that only if the minibuffer is active.  */
-  {
-    Lisp_Object tail, frame;
-
-    FOR_EACH_FRAME (tail, frame)
-      if (MINI_WINDOW_P (XWINDOW (FRAME_SELECTED_WINDOW (XFRAME (frame))))
-         && !(EQ (frame, selected_frame)
-              && minibuf_level > 0))
-       Fset_frame_selected_window (frame, Fframe_first_window (frame), Qnil);
-  }
 }
 
 DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
@@ -362,9 +338,6 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, 
Lisp_Object prompt,
   Lisp_Object histstring;
   Lisp_Object histval;
 
-  Lisp_Object empty_minibuf;
-  Lisp_Object dummy, frame;
-
   specbind (Qminibuffer_default, defalt);
   specbind (Qinhibit_read_only, Qnil);
 
@@ -416,11 +389,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, 
Lisp_Object prompt,
     {
       Lisp_Object str
        = build_string ("Command attempted to use minibuffer while in 
minibuffer");
-      if (EQ (selected_window, minibuf_window))
-       Fsignal (Quser_error, (list1 (str)));
-      else
-       /* If we're in another window, cancel the minibuffer that's active.  */
-       Fthrow (Qexit, str);
+      Fsignal (Quser_error, (list1 (str)));
     }
 
   if ((noninteractive
@@ -566,23 +535,6 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, 
Lisp_Object prompt,
   if (minibuf_level == 1 || !EQ (minibuf_window, selected_window))
     minibuf_selected_window = selected_window;
 
-  /* Empty out the minibuffers of all frames other than the one
-     where we are going to display one now.
-     Set them to point to ` *Minibuf-0*', which is always empty.  */
-  empty_minibuf = get_minibuffer (0);
-
-  FOR_EACH_FRAME (dummy, frame)
-    {
-      Lisp_Object root_window = Fframe_root_window (frame);
-      Lisp_Object mini_window = XWINDOW (root_window)->next;
-
-      if (! NILP (mini_window) && ! EQ (mini_window, minibuf_window)
-         && !NILP (Fwindow_minibuffer_p (mini_window)))
-       /* Use set_window_buffer instead of Fset_window_buffer (see
-          discussion of bug#11984, bug#12025, bug#12026).  */
-       set_window_buffer (mini_window, empty_minibuf, 0, 0);
-    }
-
   /* Display this minibuffer in the proper window.  */
   /* Use set_window_buffer instead of Fset_window_buffer (see
      discussion of bug#11984, bug#12025, bug#12026).  */


-- 
Alan Mackenzie (Nuremberg, Germany).



reply via email to

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