]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve 'display-buffer' 'temp-buffer-resize-mode' cohabitation (Bug#51062)
authorMartin Rudalics <rudalics@gmx.at>
Wed, 13 Oct 2021 07:51:27 +0000 (09:51 +0200)
committerMartin Rudalics <rudalics@gmx.at>
Wed, 13 Oct 2021 07:51:27 +0000 (09:51 +0200)
* 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.

doc/lispref/display.texi
doc/lispref/windows.texi
lisp/help.el
lisp/window.el

index 2ae04a85218ad2a4f74cbbec2dfdd15d57450296..52fe97b2993fc61fbab1d5b505f384102a805210 100644 (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
index 679744884a33df7b8e2a0e531d64f97807b274bb..d015ac1844f2701a834ed7a348af979c9e62bae0 100644 (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
index eaca33795aef6c424a0f8d2b4d8d76affad0162f..fa4eaee417d0c3ec1bb57caa4a42b7f61cec6f2d 100644 (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
index 971264b6344e28f9701b39acdb294fe2dbfb92de..1a5f2d400673ed6ac5634f1292cc252e4d7c3308 100644 (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.