Handle dedicated status in 'window--display-buffer' (Bug#33870)

* lisp/window.el (display-buffer-record-window): Rewrite
doc-string.
(window--display-buffer): Remove fifth argument DEDICATED and
either directly use a 'dedicated' entry in ALIST or the value
of 'display-buffer-mark-dedicated' instead.
(display-buffer-in-atom-window, display-buffer-use-some-frame)
(display-buffer-pop-up-frame, display-buffer-pop-up-window)
(display-buffer-below-selected, display-buffer-at-bottom):
Adjust callers of 'window--display-buffer'.
(window--make-major-side-window)
(display-buffer-in-side-window): Handle dedicated status of
the chosen side window via a 'dedicated' alist entry and
adjust 'window--display-buffer' call.
(display-buffer-in-child-frame): Set up TYPE correctly for and
adjust 'window--display-buffer' call.
(display-buffer-in-previous-window): Handle dedicated status
of a previous window already showing BUFFER.
* doc/lispref/windows.texi (Buffer Display Action Alists): New
action alist entry 'dedicated'.
(Dedicated Windows): Mention new buffer display action alist
entry 'dedicated'.
* etc/NEWS: Mention new buffer display action alist entry
'dedicated'.
This commit is contained in:
Martin Rudalics 2019-01-10 11:02:17 +01:00
parent a2e78046f6
commit f646675cd1
3 changed files with 108 additions and 63 deletions

View file

@ -2881,6 +2881,13 @@ Frames}) to avoid changing the width of other, unrelated windows.
Also, this entry should be processed under only certain conditions
which are specified right below this list.
@vindex dedicated@r{, a buffer display action alist entry}
@item dedicated
If non-@code{nil}, such an entry tells @code{display-buffer} to mark
any window it creates as dedicated to its buffer (@pxref{Dedicated
Windows}). It does that by calling @code{set-window-dedicated-p} with
the chosen window as first argument and the entry's value as second.
@vindex preserve-size@r{, a buffer display action alist entry}
@item preserve-size
If non-@code{nil} such an entry tells Emacs to preserve the size of
@ -3900,6 +3907,9 @@ display. Other functions do not treat @code{t} differently from any
non-@code{nil} value.
@end defun
You can also tell @code{display-buffer} to mark a window it creates as
dedicated to its buffer by providing a suitable @code{dedicated}
action alist entry (@pxref{Buffer Display Action Alists}).
@node Quitting Windows
@section Quitting Windows

View file

@ -1287,6 +1287,11 @@ of the Emacs Lisp Reference manual for more detail.
A buffer-local value of this hook is now run only if at least one
window showing the buffer has changed its size.
+++
** New buffer display action alist entry 'dedicated'.
Such an entry allows to specify the dedicated status of a window
created by 'display-buffer'.
+++
** New buffer display action alist entry 'window-min-height'.
Such an entry allows to specify a minimum height of the window used

View file

@ -700,8 +700,7 @@ failed."
(set-window-parameter window 'window-atom 'main))
(set-window-parameter new 'window-atom side)
;; Display BUFFER in NEW and return NEW.
(window--display-buffer
buffer new 'window alist display-buffer-mark-dedicated))))
(window--display-buffer buffer new 'window alist))))
(defun window--atom-check-1 (window)
"Subroutine of `window--atom-check'."
@ -958,7 +957,11 @@ and may be called only if no window on SIDE exists yet."
;; window and not make a new parent window unless needed.
(window-combination-resize 'side)
(window-combination-limit nil)
(window (split-window-no-error next-to nil on-side)))
(window (split-window-no-error next-to nil on-side))
(alist (if (assq 'dedicated alist)
alist
(cons `(dedicated . ,(or display-buffer-mark-dedicated 'side))
alist))))
(when window
;; Initialize `window-side' parameter of new window to SIDE and
;; make that parameter persistent.
@ -985,7 +988,7 @@ and may be called only if no window on SIDE exists yet."
(with-current-buffer buffer
(setq window--sides-shown t))
;; Install BUFFER in new window and return WINDOW.
(window--display-buffer buffer window 'window alist 'side))))
(window--display-buffer buffer window 'window alist))))
(defun display-buffer-in-side-window (buffer alist)
"Display BUFFER in a side window of the selected frame.
@ -1019,10 +1022,7 @@ nor installs any other window parameters unless they have been
explicitly provided via a `window-parameters' entry in ALIST."
(let* ((side (or (cdr (assq 'side alist)) 'bottom))
(slot (or (cdr (assq 'slot alist)) 0))
(left-or-right (memq side '(left right)))
;; Softly dedicate window to BUFFER unless
;; `display-buffer-mark-dedicated' already asks for it.
(dedicated (or display-buffer-mark-dedicated 'side)))
(left-or-right (memq side '(left right))))
(cond
((not (memq side '(top bottom left right)))
(error "Invalid side %s specified" side))
@ -1055,7 +1055,11 @@ explicitly provided via a `window-parameters' entry in ALIST."
((eq side 'bottom) 3))
window-sides-slots))
(window--sides-inhibit-check t)
window this-window this-slot prev-window next-window
(alist (if (assq 'dedicated alist)
alist
(cons `(dedicated . ,(or display-buffer-mark-dedicated 'side))
alist)))
window this-window this-slot prev-window next-window
best-window best-slot abs-slot)
(cond
@ -1113,8 +1117,7 @@ explicitly provided via a `window-parameters' entry in ALIST."
;; Reuse `this-window'.
(with-current-buffer buffer
(setq window--sides-shown t))
(window--display-buffer
buffer this-window 'reuse alist dedicated))
(window--display-buffer buffer this-window 'reuse alist))
(and (or (not max-slots) (< slots max-slots))
(or (and next-window
;; Make new window before `next-window'.
@ -1131,8 +1134,7 @@ explicitly provided via a `window-parameters' entry in ALIST."
(set-window-parameter window 'window-slot slot)
(with-current-buffer buffer
(setq window--sides-shown t))
(window--display-buffer
buffer window 'window alist dedicated))
(window--display-buffer buffer window 'window alist))
(and best-window
;; Reuse `best-window'.
(progn
@ -1141,7 +1143,7 @@ explicitly provided via a `window-parameters' entry in ALIST."
(with-current-buffer buffer
(setq window--sides-shown t))
(window--display-buffer
buffer best-window 'reuse alist dedicated)))))))))
buffer best-window 'reuse alist)))))))))
(defun window-toggle-side-windows (&optional frame)
"Toggle display of side windows on specified FRAME.
@ -6073,23 +6075,26 @@ not resized by this function."
(defun display-buffer-record-window (type window buffer)
"Record information for window used by `display-buffer'.
TYPE specifies the type of the calling operation and must be one
of the symbols `reuse' (when WINDOW existed already and was
reused for displaying BUFFER), `window' (when WINDOW was created
on an already existing frame), or `frame' (when WINDOW was
created on a new frame). WINDOW is the window used for or created
by the `display-buffer' routines. BUFFER is the buffer that
shall be displayed.
WINDOW is the window used for or created by a buffer display
action function. BUFFER is the buffer to display. Note that
this function must be called before BUFFER is explicitly made
WINDOW's buffer (although WINDOW may show BUFFER already).
This function installs or updates the quit-restore parameter of
WINDOW. The quit-restore parameter is a list of four elements:
The first element is one of the symbols `window', `frame', `same' or
`other'. The second element is either one of the symbols `window'
or `frame' or a list whose elements are the buffer previously
shown in the window, that buffer's window start and window point,
and the window's height. The third element is the window
selected at the time the parameter was created. The fourth
element is BUFFER."
TYPE specifies the type of the calling operation and must be one
of the symbols 'reuse' (meaning that WINDOW exists already and
will be used for displaying BUFFER), 'window' (WINDOW was created
on an already existing frame) or 'frame' (WINDOW was created on a
new frame).
This function installs or updates the 'quit-restore' parameter of
WINDOW. The 'quit-restore' parameter is a list of four elements:
The first element is one of the symbols 'window', 'frame', 'same'
or 'other'. The second element is either one of the symbols
'window' or 'frame' or a list whose elements are the buffer
previously shown in the window, that buffer's window start and
window point, and the window's height. The third element is the
window selected at the time the parameter was created. The
fourth element is BUFFER."
(cond
((eq type 'reuse)
(if (eq (window-buffer window) buffer)
@ -6748,20 +6753,51 @@ window is larger than WINDOW."
(/ (- (window-total-height window) (window-total-height)) 2))
(error nil))))))
(defun window--display-buffer (buffer window type &optional alist dedicated)
(defun window--display-buffer (buffer window type &optional alist)
"Display BUFFER in WINDOW.
TYPE must be one of the symbols `reuse', `window' or `frame' and
is passed unaltered to `display-buffer-record-window'. ALIST is
the alist argument of `display-buffer'. Set `window-dedicated-p'
to DEDICATED if non-nil. Return WINDOW if BUFFER and WINDOW are
live."
WINDOW must be a live window chosen by a buffer display action
function for showing BUFFER. TYPE tells whether WINDOW existed
already before that action function was called or is a new window
created by that function. ALIST is a buffer display action alist
as compiled by `display-buffer'.
TYPE must be one of the following symbols: 'reuse' (which means
WINDOW existed before the call of `display-buffer' and may
already show BUFFER or not), 'window' (WINDOW was created on an
existing frame) or 'frame' (WINDOW was created on a new frame).
TYPE is passed unaltered to `display-buffer-record-window'.
Handle WINDOW's dedicated flag as follows: If WINDOW already
shows BUFFER, leave it alone. Otherwise, if ALIST contains a
'dedicated' entry and WINDOW is either new or that entry's value
equals 'side', set WINDOW's dedicated flag to the value of that
entry. Otherwise, if WINDOW is new and the value of
'display-buffer-mark-dedicated' is non-nil, set WINDOW's
dedicated flag to that value. In any other case, reset WINDOW's
dedicated flag to nil.
Return WINDOW if BUFFER and WINDOW are live."
(when (and (buffer-live-p buffer) (window-live-p window))
(display-buffer-record-window type window buffer)
(unless (eq buffer (window-buffer window))
;; Unless WINDOW already shows BUFFER reset its dedicated flag.
(set-window-dedicated-p window nil)
(set-window-buffer window buffer))
(when dedicated
(set-window-dedicated-p window dedicated))
(let ((alist-dedicated (assq 'dedicated alist)))
;; Maybe dedicate WINDOW to BUFFER if asked for.
(cond
;; Don't dedicate WINDOW if it is dedicated because it shows
;; BUFFER already or it is reused and is not a side window.
((or (window-dedicated-p window)
(and (eq type 'reuse) (not (eq (cdr alist-dedicated) 'side)))))
;; Otherwise, if ALIST contains a 'dedicated' entry, use that
;; entry's value (which may be nil).
(alist-dedicated
(set-window-dedicated-p window (cdr alist-dedicated)))
;; Otherwise, if 'display-buffer-mark-dedicated' is non-nil,
;; use that.
(display-buffer-mark-dedicated
(set-window-dedicated-p window display-buffer-mark-dedicated))))
(when (memq type '(window frame))
(set-window-prev-buffers window nil))
(let ((quit-restore (window-parameter window 'quit-restore))
@ -7190,8 +7226,7 @@ that allows the selected frame)."
frame nil (cdr (assq 'inhibit-same-window alist))))))
(when window
(prog1
(window--display-buffer
buffer window 'reuse alist display-buffer-mark-dedicated)
(window--display-buffer buffer window 'reuse alist)
(unless (cdr (assq 'inhibit-switch-frame alist))
(window--maybe-raise-frame frame))))))
@ -7356,8 +7391,7 @@ new frame."
(with-current-buffer buffer
(setq frame (funcall fun)))
(setq window (frame-selected-window frame)))
(prog1 (window--display-buffer
buffer window 'frame alist display-buffer-mark-dedicated)
(prog1 (window--display-buffer buffer window 'frame alist)
(unless (cdr (assq 'inhibit-switch-frame alist))
(window--maybe-raise-frame frame))))))
@ -7386,8 +7420,7 @@ raising the frame."
(window--try-to-split-window
(get-lru-window frame t) alist))))
(prog1 (window--display-buffer
buffer window 'window alist display-buffer-mark-dedicated)
(prog1 (window--display-buffer buffer window 'window alist)
(unless (cdr (assq 'inhibit-switch-frame alist))
(window--maybe-raise-frame (window-frame window)))))))
@ -7435,7 +7468,7 @@ be added to ALIST."
(parent (or (assq 'parent-frame parameters)
(selected-frame)))
(share (assq 'share-child-frame parameters))
share1 frame window)
share1 frame window type)
(with-current-buffer buffer
(when (frame-live-p parent)
(catch 'frame
@ -7448,12 +7481,14 @@ be added to ALIST."
(throw 'frame t))))))
(if frame
(setq window (frame-selected-window frame))
(progn
(setq window (frame-selected-window frame))
(setq type 'reuse))
(setq frame (make-frame parameters))
(setq window (frame-selected-window frame))))
(setq window (frame-selected-window frame))
(setq type 'frame)))
(prog1 (window--display-buffer
buffer window 'frame alist display-buffer-mark-dedicated)
(prog1 (window--display-buffer buffer window type alist)
(unless (cdr (assq 'inhibit-switch-frame alist))
(window--maybe-raise-frame frame)))))
@ -7492,16 +7527,14 @@ must also contain a 'window-height' entry with the same value."
split-width-threshold)
(setq window (window--try-to-split-window
(selected-window) alist)))
(window--display-buffer
buffer window 'window alist display-buffer-mark-dedicated))
(window--display-buffer buffer window 'window alist))
(and (setq window (window-in-direction 'below))
(not (window-dedicated-p window))
(or (not (numberp min-height))
;; A window that showed another buffer before cannot
;; be resized.
(>= (window-height window) min-height))
(window--display-buffer
buffer window 'reuse alist display-buffer-mark-dedicated)))))
(window--display-buffer buffer window 'reuse alist)))))
(defun display-buffer--maybe-at-bottom (buffer alist)
(let ((alist (append alist `(,(if temp-buffer-resize-mode
@ -7533,21 +7566,17 @@ selected frame."
(setq bottom-window window))))
nil nil 'nomini)
(or (and bottom-window-shows-buffer
(window--display-buffer
buffer bottom-window 'reuse alist display-buffer-mark-dedicated))
(window--display-buffer buffer bottom-window 'reuse alist))
(and (not (frame-parameter nil 'unsplittable))
(let (split-width-threshold)
(let (split-height-threshold)
(setq window (window--try-to-split-window bottom-window alist)))
(window--display-buffer
buffer window 'window alist display-buffer-mark-dedicated))
(window--display-buffer buffer window 'window alist))
(and (not (frame-parameter nil 'unsplittable))
(setq window (split-window-no-error (window-main-window)))
(window--display-buffer
buffer window 'window alist display-buffer-mark-dedicated))
(window--display-buffer buffer window 'window alist))
(and (setq window bottom-window)
(not (window-dedicated-p window))
(window--display-buffer
buffer window 'reuse alist display-buffer-mark-dedicated)))))
(window--display-buffer buffer window 'reuse alist)))))
(defun display-buffer-in-previous-window (buffer alist)
"Display BUFFER in a window previously showing it.
@ -7596,7 +7625,8 @@ above, even if that window never showed BUFFER before."
;; anything we found so far.
(when (and (setq window (cdr (assq 'previous-window alist)))
(window-live-p window)
(not (window-dedicated-p window)))
(or (eq buffer (window-buffer window))
(not (window-dedicated-p window))))
(if (eq window (selected-window))
(unless inhibit-same-window
(setq second-best-window window))