From 1a1062d6e16f97effa7030cc5f297c9c57b232ad Mon Sep 17 00:00:00 2001 From: Martin Rudalics Date: Sun, 21 Aug 2016 11:36:11 +0200 Subject: [PATCH] Fix semantics of 'minibuffer' frame parameter The 'minibuffer' frame parameter is now t for a normal frame (a frame with a root window plus a minibuffer window) and the frame's minibuffer window for a minibuffer-less frame (a frame whose minibuffer window is on another frame). See also: https://lists.gnu.org/archive/html/emacs-devel/2016-07/msg01259.html * src/frame.c (make_frame, make_frame_without_minibuffer) (make_minibuffer_frame): When assigning the frame's minibuffer window also store corresponding 'minibuffer' frame parameter. (store_frame_param): Move the 'minibuffer' parameter checks to the beginning so we can silently override the value before it gets stored in the parameter alist. Fix error handling. (Fframe_parameters): Return value of 'minibuffer' parameter unmodified. * lisp/frameset.el (frameset-filter-minibuffer): When the cdr of the parameter is a minibuffer window, save (minibuffer . nil) instead of (minibuffer . t). (frameset--reuse-frame): To find a non-minibuffer-only frame look out for a frame whose 'minibuffer' parameter is t instead of that frame's minibuffer window. (frameset-minibufferless-first-p): To find a minibuffer-less frame look out for a frame whose 'minibuffer' parameter is a window instead of nil. --- lisp/frameset.el | 24 +++++++++++++++-------- src/frame.c | 60 ++++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 59 insertions(+), 25 deletions(-) diff --git a/lisp/frameset.el b/lisp/frameset.el index 2453f57e228..9a7a8bcf8b0 100644 --- a/lisp/frameset.el +++ b/lisp/frameset.el @@ -572,7 +572,7 @@ see `frameset-filter-alist'." (defun frameset-filter-minibuffer (current filtered _parameters saving) "Force the minibuffer parameter to have a sensible value. -When saving, convert (minibuffer . #) to (minibuffer . t). +When saving, convert (minibuffer . #) to (minibuffer . nil). When restoring, if there are two copies, keep the one pointing to a live window. @@ -580,7 +580,12 @@ For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, see `frameset-filter-alist'." (let ((value (cdr current)) mini) (cond (saving - (if (windowp value) '(minibuffer . t) t)) + ;; "Fix semantics of 'minibuffer' frame parameter" change: + ;; When the cdr of the parameter is a minibuffer window, save + ;; (minibuffer . nil) instead of (minibuffer . t). + (if (windowp value) + '(minibuffer . nil) + t)) ((setq mini (assq 'minibuffer filtered)) (when (windowp value) (setcdr mini value)) nil) @@ -906,12 +911,12 @@ is the parameter alist of the frame being restored. Internal use only." ;; If it has not been loaded, and it is not a minibuffer-only frame, ;; let's look for an existing non-minibuffer-only frame to reuse. (unless (or frame (eq (cdr (assq 'minibuffer parameters)) 'only)) + ;; "Fix semantics of 'minibuffer' frame parameter" change: + ;; The 'minibuffer' frame parameter of a non-minibuffer-only + ;; frame is t instead of that frame's minibuffer window. (setq frame (frameset--find-frame-if (lambda (f) - (let ((w (frame-parameter f 'minibuffer))) - (and (window-live-p w) - (window-minibuffer-p w) - (eq (window-frame w) f)))) + (eq (frame-parameter f 'minibuffer) t)) display)))) (mini ;; For minibufferless frames, check whether they already exist, @@ -1027,8 +1032,11 @@ For the meaning of FORCE-DISPLAY, see `frameset-restore'." (t (not force-display)))) (defun frameset-minibufferless-first-p (frame1 _frame2) - "Predicate to sort minibufferless frames before other frames." - (not (frame-parameter frame1 'minibuffer))) + "Predicate to sort minibuffer-less frames before other frames." + ;; "Fix semantics of 'minibuffer' frame parameter" change: The + ;; 'minibuffer' frame parameter of a minibuffer-less frame is that + ;; frame's minibuffer window instead of nil. + (windowp (frame-parameter frame1 'minibuffer))) ;;;###autoload (cl-defun frameset-restore (frameset diff --git a/src/frame.c b/src/frame.c index 899c315016b..e17c8acfc3c 100644 --- a/src/frame.c +++ b/src/frame.c @@ -658,6 +658,7 @@ make_frame (bool mini_p) mw->mini = 1; wset_frame (mw, frame); fset_minibuffer_window (f, mini_window); + store_frame_param (f, Qminibuffer, Qt); } else { @@ -770,6 +771,7 @@ make_frame_without_minibuffer (Lisp_Object mini_window, KBOARD *kb, } fset_minibuffer_window (f, mini_window); + store_frame_param (f, Qminibuffer, mini_window); /* Make the chosen minibuffer window display the proper minibuffer, unless it is already showing a minibuffer. */ @@ -807,6 +809,7 @@ make_minibuffer_frame (void) mini_window = f->root_window; fset_minibuffer_window (f, mini_window); + store_frame_param (f, Qminibuffer, Qonly); XWINDOW (mini_window)->mini = 1; wset_next (XWINDOW (mini_window), Qnil); wset_prev (XWINDOW (mini_window), Qnil); @@ -2404,6 +2407,46 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val) { register Lisp_Object old_alist_elt; + if (EQ (prop, Qminibuffer)) + { + if (WINDOWP (val)) + { + if (!MINI_WINDOW_P (XWINDOW (val))) + error ("The 'minibuffer' parameter does not specify a valid minibuffer window"); + else if (FRAME_MINIBUF_ONLY_P (f)) + { + if (EQ (val, FRAME_MINIBUF_WINDOW (f))) + val = Qonly; + else + error ("Can't change the minibuffer window of a minibuffer-only frame"); + } + else if (FRAME_HAS_MINIBUF_P (f)) + { + if (EQ (val, FRAME_MINIBUF_WINDOW (f))) + val = Qt; + else + error ("Can't change the minibuffer window of a frame with its own minibuffer"); + } + else + /* Store the chosen minibuffer window. */ + fset_minibuffer_window (f, val); + } + else + { + Lisp_Object old_val = Fcdr (Fassq (Qminibuffer, f->param_alist)); + + if (!NILP (old_val)) + { + if (WINDOWP (old_val) && NILP (val)) + /* Don't change the value for a minibuffer-less frame if + only nil was specified as new value. */ + val = old_val; + else if (!EQ (old_val, val)) + error ("Can't change the 'minibuffer' parameter of this frame"); + } + } + } + /* The buffer-list parameters are stored in a special place and not in the alist. All buffers must be live. */ if (EQ (prop, Qbuffer_list)) @@ -2475,19 +2518,6 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val) else if (EQ (prop, Qname)) set_term_frame_name (f, val); } - - if (EQ (prop, Qminibuffer) && WINDOWP (val)) - { - if (! MINI_WINDOW_P (XWINDOW (val))) - error ("Surrogate minibuffer windows must be minibuffer windows"); - - if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f)) - && !EQ (val, f->minibuffer_window)) - error ("Can't change the surrogate minibuffer of a frame with its own minibuffer"); - - /* Install the chosen minibuffer window, with proper buffer. */ - fset_minibuffer_window (f, val); - } } /* Return color matches UNSPEC on frame F or nil if UNSPEC @@ -2565,10 +2595,6 @@ If FRAME is omitted or nil, return information on the currently selected frame. : FRAME_COLS (f)); store_in_alist (&alist, Qwidth, make_number (width)); store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil)); - store_in_alist (&alist, Qminibuffer, - (! FRAME_HAS_MINIBUF_P (f) ? Qnil - : FRAME_MINIBUF_ONLY_P (f) ? Qonly - : FRAME_MINIBUF_WINDOW (f))); store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil)); store_in_alist (&alist, Qbuffer_list, f->buffer_list); store_in_alist (&alist, Qburied_buffer_list, f->buried_buffer_list); -- 2.11.4.GIT