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:
parent
a2e78046f6
commit
f646675cd1
3 changed files with 108 additions and 63 deletions
|
@ -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
|
||||
|
|
5
etc/NEWS
5
etc/NEWS
|
@ -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
|
||||
|
|
156
lisp/window.el
156
lisp/window.el
|
@ -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))
|
||||
|
|
Loading…
Add table
Reference in a new issue