1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-12-04 08:47:11 +00:00

Improve 'display-buffer' 'temp-buffer-resize-mode' cohabitation (Bug#51062)

* doc/lispref/display.texi (Temporary Displays): Explain how
to override the effect of 'temp-buffer-resize-mode' with a
suitable 'display-buffer' action alist entry.
* doc/lispref/windows.texi (Buffer Display Action Alists):
Mention that an 'inhibit-switch-frame' entry might not work
with every WM.  Describe the 'window-size' entry.  Describe
how automatic window resizing can be overridden.
* lisp/help.el (resize-temp-buffer-window-inhibit): New variable.
(resize-temp-buffer-window): Handle case where user overrides
automatic resizing.
* lisp/window.el (temp-buffer-window-show): Bind
'resize-temp-buffer-window-inhibit' to nil around
'display-buffer'.  Do not raise frame automatically to avoid
defeating 'inhibit-switch-frame'.
(window--display-buffer): Set 'resize-temp-buffer-window-inhibit'
to t when the action alist contains a 'window-height',
'window-width' or 'window-size' entry.  Use
'modify-frame-parameters' instead of 'set-frame-height' and
'set-frame-width' to avoid that the latter step on each others
toes.
(display-buffer): Fix 'inhibit-switch-frame' part in and add
'window-size' part to doc-string.
This commit is contained in:
Martin Rudalics 2021-10-13 09:51:27 +02:00
parent dec613d1e7
commit 2223c519a5
4 changed files with 116 additions and 48 deletions

View File

@ -1334,6 +1334,11 @@ are not resized. By default, this mode uses @code{fit-window-to-buffer}
(@pxref{Resizing Windows}) for resizing. You can specify a different
function by customizing the options @code{temp-buffer-max-height} and
@code{temp-buffer-max-width} below.
The effect of this option can be overridden by providing a suitable
@code{window-height}, @code{window-width} or @code{window-size} action
alist entry for @code{display-buffer} (@pxref{Buffer Display Action
Alists}).
@end defopt
@defopt temp-buffer-max-height

View File

@ -2924,9 +2924,9 @@ A non-@code{nil} value prevents another frame from being raised or
selected, if the window chosen by @code{display-buffer} is displayed
there. Primarily affected by this are
@code{display-buffer-use-some-frame} and
@code{display-buffer-reuse-window}.
@code{display-buffer-pop-up-frame} should be affected as well, but
there is no guarantee that the window manager will comply.
@code{display-buffer-reuse-window}. Ideally,
@code{display-buffer-pop-up-frame} should be affected as well, but there
is no guarantee that the window manager will comply.
@vindex window-parameters@r{, a buffer display action alist entry}
@item window-parameters
@ -2972,8 +2972,8 @@ root window.
If the value specifies a function, that function is called with one
argument---the chosen window. The function is supposed to adjust the
height of the window; its return value is ignored. Suitable functions
are @code{shrink-window-if-larger-than-buffer} and
@code{fit-window-to-buffer}, see @ref{Resizing Windows}.
are @code{fit-window-to-buffer} and
@code{shrink-window-if-larger-than-buffer}, see @ref{Resizing Windows}.
@end itemize
By convention, the height of the chosen window is adjusted only if the
@ -3007,11 +3007,31 @@ argument---the chosen window. The function is supposed to adjust the
width of the window; its return value is ignored.
@end itemize
By convention, the width of the chosen window is adjusted only if the
window is part of a horizontal combination (@pxref{Windows and
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 window-size@r{, a buffer display action alist entry}
@item window-size
This entry is a combination of the two preceding ones and can be used to
adjust the chosen window's height and width. Since windows can be
resized in one direction only without affecting other windows,
@code{window-size} is effective only to set up the size of a window
appearing alone on a frame. The value can be one of the following:
@itemize @bullet
@item
@code{nil} means to leave the size of the chosen window alone.
@item
A cons cell of two integers specifies the desired total width and height
of the chosen window in lines and columns. It's effect is to adjust the
size of the frame accordingly.
@item
If the value specifies a function, that function is called with one
argument---the chosen window. The function is supposed to adjust the
size of the window's frame; its return value is ignored.
@end itemize
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
@ -3112,6 +3132,14 @@ the window was created earlier by @code{display-buffer} to show the
buffer and never was used to show another buffer until it was reused
by the current invocation of @code{display-buffer}.
If no @code{window-height}, @code{window-width} or @code{window-size}
entry was specified, the window may still be resized automatically when
the buffer is temporary and @code{temp-buffer-resize-mode} has been
enabled, @ref{Temporary Displays}. In that case, the @sc{cdr} of a
@code{window-height}, @code{window-width} or @code{window-size} entry
can be used to inhibit or override the default behavior of
@code{temp-buffer-resize-mode} for specific buffers or invocations of
@code{display-buffer}.
@node Choosing Window Options
@subsection Additional Options for Displaying Buffers

View File

@ -1596,10 +1596,16 @@ and some others."
(add-hook 'temp-buffer-show-hook 'resize-temp-buffer-window 'append)
(remove-hook 'temp-buffer-show-hook 'resize-temp-buffer-window)))
(defvar resize-temp-buffer-window-inhibit nil
"Non-nil means `resize-temp-buffer-window' should not resize.")
(defun resize-temp-buffer-window (&optional window)
"Resize WINDOW to fit its contents.
WINDOW must be a live window and defaults to the selected one.
Do not resize if WINDOW was not created by `display-buffer'.
Do not resize if WINDOW was not created by `display-buffer'. Do
not resize either if a `window-height', `window-width' or
`window-size' entry in `display-buffer-alist' prescribes some
alternative resizing for WINDOW's buffer.
If WINDOW is part of a vertical combination, restrain its new
size by `temp-buffer-max-height' and do not resize if its minimum
@ -1614,27 +1620,33 @@ provided `fit-frame-to-buffer' is non-nil.
This function may call `preserve-window-size' to preserve the
size of WINDOW."
(setq window (window-normalize-window window t))
(let ((height (if (functionp temp-buffer-max-height)
(let* ((buffer (window-buffer window))
(height (if (functionp temp-buffer-max-height)
(with-selected-window window
(funcall temp-buffer-max-height buffer))
temp-buffer-max-height))
(width (if (functionp temp-buffer-max-width)
(with-selected-window window
(funcall temp-buffer-max-height (window-buffer)))
temp-buffer-max-height))
(width (if (functionp temp-buffer-max-width)
(with-selected-window window
(funcall temp-buffer-max-width (window-buffer)))
temp-buffer-max-width))
(quit-cadr (cadr (window-parameter window 'quit-restore))))
;; Resize WINDOW iff it was made by `display-buffer'.
(funcall temp-buffer-max-width buffer))
temp-buffer-max-width))
(quit-cadr (cadr (window-parameter window 'quit-restore))))
;; Resize WINDOW only if it was made by `display-buffer'.
(when (or (and (eq quit-cadr 'window)
(or (and (window-combined-p window)
(not (eq fit-window-to-buffer-horizontally
'only))
(pos-visible-in-window-p (point-min) window))
(pos-visible-in-window-p
(with-current-buffer buffer (point-min))
window)
(not resize-temp-buffer-window-inhibit))
(and (window-combined-p window t)
fit-window-to-buffer-horizontally)))
fit-window-to-buffer-horizontally
(not resize-temp-buffer-window-inhibit))))
(and (eq quit-cadr 'frame)
fit-frame-to-buffer
(eq window (frame-root-window window))))
(fit-window-to-buffer window height nil width nil t))))
(eq window (frame-root-window window))
(not resize-temp-buffer-window-inhibit)))
(fit-window-to-buffer window height nil width nil t))))
;;; Help windows.
(defcustom help-window-select nil

View File

@ -108,11 +108,14 @@ Return the buffer."
;; Return the buffer.
buffer)))
;; Defined in help.el.
(defvar resize-temp-buffer-window-inhibit)
(defun temp-buffer-window-show (buffer &optional action)
"Show temporary buffer BUFFER in a window.
Return the window showing BUFFER. Pass ACTION as action argument
to `display-buffer'."
(let (window frame)
(let (resize-temp-buffer-window-inhibit window)
(with-current-buffer buffer
(set-buffer-modified-p nil)
(setq buffer-read-only t)
@ -130,9 +133,9 @@ to `display-buffer'."
t
window-combination-limit)))
(setq window (display-buffer buffer action)))
(setq frame (window-frame window))
(unless (eq frame (selected-frame))
(raise-frame frame))
;; We used to raise the window's frame here. Do not do that
;; since it would override an `inhibit-switch-frame' entry
;; specified for the action alist used by `display-buffer'.
(setq minibuffer-scroll-window window)
(set-window-hscroll window 0)
(with-selected-window window
@ -7246,11 +7249,14 @@ Return WINDOW if BUFFER and WINDOW are live."
(inhibit-modification-hooks t))
(funcall (cdr (assq 'body-function alist)) window)))
(let ((quit-restore (window-parameter window 'quit-restore))
(height (cdr (assq 'window-height alist)))
(width (cdr (assq 'window-width alist)))
(size (cdr (assq 'window-size alist)))
(preserve-size (cdr (assq 'preserve-size alist))))
(let* ((quit-restore (window-parameter window 'quit-restore))
(window-height (assq 'window-height alist))
(height (cdr window-height))
(window-width (assq 'window-width alist))
(width (cdr window-width))
(window-size (assq 'window-size alist))
(size (cdr window-size))
(preserve-size (cdr (assq 'preserve-size alist))))
(cond
((or (eq type 'frame)
(and (eq (car quit-restore) 'same)
@ -7267,14 +7273,18 @@ Return WINDOW if BUFFER and WINDOW are live."
(height (cdr size))
(frame (window-frame window)))
(when (and (numberp width) (numberp height))
(set-frame-height
frame (+ (frame-height frame)
(- height (window-total-height window))))
(set-frame-width
frame (+ (frame-width frame)
(- width (window-total-width window)))))))
;; Modifying the parameters of a newly created frame might
;; not work everywhere, but then `temp-buffer-resize-mode'
;; will certainly fail in a similar fashion.
(modify-frame-parameters
frame `((height . ,(+ (frame-height frame)
(- height (window-total-height window))))
(width . ,(+ (frame-width frame)
(- width (window-total-width window))))))))
(setq resize-temp-buffer-window-inhibit t))
((functionp size)
(ignore-errors (funcall size window)))))
(ignore-errors (funcall size window))
(setq resize-temp-buffer-window-inhibit t))))
((or (eq type 'window)
(and (eq (car quit-restore) 'same)
(eq (nth 1 quit-restore) 'window)))
@ -7294,9 +7304,11 @@ Return WINDOW if BUFFER and WINDOW are live."
(delta (- new-height (window-total-height window))))
(when (and (window--resizable-p window delta nil 'safe)
(window-combined-p window))
(window-resize window delta nil 'safe))))
(window-resize window delta nil 'safe)))
(setq resize-temp-buffer-window-inhibit 'vertical))
((functionp height)
(ignore-errors (funcall height window))))
(ignore-errors (funcall height window))
(setq resize-temp-buffer-window-inhibit 'vertical)))
;; Adjust width of window if asked for.
(cond
((not width))
@ -7310,9 +7322,11 @@ Return WINDOW if BUFFER and WINDOW are live."
(delta (- new-width (window-total-width window))))
(when (and (window--resizable-p window delta t 'safe)
(window-combined-p window t))
(window-resize window delta t 'safe))))
(window-resize window delta t 'safe)))
(setq resize-temp-buffer-window-inhibit 'horizontal))
((functionp width)
(ignore-errors (funcall width window))))
(ignore-errors (funcall width window))
(setq resize-temp-buffer-window-inhibit 'horizontal)))
;; Preserve window size if asked for.
(when (consp preserve-size)
(window-preserve-size window t (car preserve-size))
@ -7557,9 +7571,11 @@ perform.
Action alist entries are:
`inhibit-same-window' -- A non-nil value prevents the same
window from being used for display.
`inhibit-switch-frame' -- A non-nil value prevents any frame
used for showing the buffer from being raised or selected.
`reusable-frames' -- The value specifies the set of frames to
`inhibit-switch-frame' -- A non-nil value prevents any frame used
for showing the buffer from being raised or selected. Note
that a window manager may still raise a new frame and give it
focus, effectively overriding the value specified here.
`reusable-frames' -- The value specifies the set of frames to
search for a window that already displays the buffer.
Possible values are nil (the selected frame), t (any live
frame), visible (any visible frame), 0 (any visible or
@ -7582,7 +7598,14 @@ Action alist entries are:
window) or a function to be called with one argument - the
chosen window. The function is supposed to adjust the width
of the window; its return value is ignored.
`preserve-size' -- The value should be either (t . nil) to
`window-size' -- This entry is only useful for windows appearing
alone on their frame and specifies the desired size of that
window either as a cons of integers (the total width and
height of the window on that frame), or a function to be
called with one argument - the chosen window. The function
is supposed to adjust the size of the frame; its return value
is ignored.
`preserve-size' -- The value should be either (t . nil) to
preserve the width of the chosen window, (nil . t) to
preserve its height or (t . t) to preserve its height and
width in future changes of the window configuration.