emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master e3f97d7: Fixes for fitting windows and frames to th


From: Martin Rudalics
Subject: [Emacs-diffs] master e3f97d7: Fixes for fitting windows and frames to their buffers (Bug#37563)
Date: Fri, 11 Oct 2019 02:47:28 -0400 (EDT)

branch: master
commit e3f97d73653df725322d7f2392d36f858cce5a73
Author: Martin Rudalics <address@hidden>
Commit: Martin Rudalics <address@hidden>

    Fixes for fitting windows and frames to their buffers (Bug#37563)
    
    * lisp/window.el (window-default-font-height)
    (window-default-line-height): New functions.
    (fit-frame-to-buffer): Interpret values of MAX-HEIGHT and
    MIN-HEIGHT arguments in terms of WINDOW's default line height
    (Bug#37563).
    (fit-window-to-buffer): Obey size restricting arguments even
    when size of WINDOW's text does not change.  Do not
    temporarily select WINDOW and perform height/width related
    calculations if and only if WINDOW is accordingly combined.
    Interpret values of MAX-HEIGHT and MIN-HEIGHT arguments in
    terms of WINDOW's default line height.
---
 lisp/window.el | 252 ++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 141 insertions(+), 111 deletions(-)

diff --git a/lisp/window.el b/lisp/window.el
index d93ec0a..fafb6f9 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -8501,6 +8501,41 @@ WINDOW must be a live window and defaults to the 
selected one."
                             (eobp)
                             window))))
 
+(defun window-default-font-height (&optional window)
+  "Return height in pixels of WINDOW's default face font.
+WINDOW must be a live window and defaults to the selected one.
+
+The return value accounts for any remapping of the default face
+font on WINDOW's frame."
+  (let* ((window (window-normalize-window window t))
+        (frame (window-frame window))
+        (default-font (face-font 'default frame)))
+    (if (and (display-multi-font-p (frame-parameter frame 'display))
+            (not (string-equal (frame-parameter frame 'font) default-font)))
+        (aref (font-info default-font frame) 3)
+      (frame-char-height frame))))
+
+(defun window-default-line-height (&optional window)
+  "Return height in pixels of a text line in WINDOW.
+WINDOW must be a live window and defaults to the selected one.
+
+The return value includes any line spacing defined for WINDOW's
+buffer or frame and accounts for any remapping of the default
+face on WINDOW's frame."
+  (let* ((window (window-normalize-window window t))
+        (font-height (window-default-font-height window))
+        (frame (window-frame window))
+        (buffer (window-buffer window))
+        (space-height
+         (or (and (display-graphic-p frame)
+                  (or (buffer-local-value 'line-spacing buffer)
+                      (frame-parameter frame 'line-spacing)))
+             0)))
+    (+ font-height
+       (if (floatp space-height)
+           (truncate (* (frame-char-height frame) space-height))
+         space-height))))
+
 ;;; Resizing windows and frames to fit their contents exactly.
 (defcustom fit-window-to-buffer-horizontally nil
   "Non-nil means `fit-window-to-buffer' can resize windows horizontally.
@@ -8643,6 +8678,7 @@ parameters of FRAME."
            (char-height (frame-char-height frame))
            ;; WINDOW is FRAME's root window.
            (window (frame-root-window frame))
+           (line-height (window-default-line-height window))
            (parent (frame-parent frame))
            (monitor-attributes
             (unless parent
@@ -8739,16 +8775,16 @@ parameters of FRAME."
            (max-height
             (min
              (cond
-              ((numberp max-height) (* max-height char-height))
-              ((numberp (nth 0 sizes)) (* (nth 0 sizes) char-height))
+              ((numberp max-height) (* max-height line-height))
+              ((numberp (nth 0 sizes)) (* (nth 0 sizes) line-height))
               (t parent-or-display-height))
              ;; The following is the maximum height that fits into the
              ;; top and bottom margins.
              (max (- bottom-margin top-margin outer-minus-body-height))))
            (min-height
             (cond
-             ((numberp min-height) (* min-height char-height))
-             ((numberp (nth 1 sizes)) (* (nth 1 sizes) char-height))
+             ((numberp min-height) (* min-height line-height))
+             ((numberp (nth 1 sizes)) (* (nth 1 sizes) line-height))
              (t (window-min-size window nil nil t))))
            (max-width
             (min
@@ -8871,124 +8907,118 @@ accessible position."
         max-height min-height max-width min-width
         (and (memq fit-frame-to-buffer '(vertically horizontally))
              fit-frame-to-buffer)))
-    (with-selected-window window
-      (let* ((pixelwise window-resize-pixelwise)
-            (char-height (frame-char-height))
-            (char-width (frame-char-width))
-            (total-height (window-size window nil pixelwise))
-            (body-height (window-body-height window pixelwise))
-            (body-width (window-body-width window pixelwise))
-            (min-height
-             ;; Sanitize MIN-HEIGHT.
-             (if (numberp min-height)
-                 ;; Can't get smaller than `window-safe-min-height'.
-                 (max (if pixelwise
-                          (* char-height min-height)
-                        min-height)
-                      (if pixelwise
-                          (window-safe-min-pixel-height window)
-                        window-safe-min-height))
-               ;; Preserve header and mode line if present.
-               (max (if pixelwise
-                        (* char-height window-min-height)
-                      window-min-height)
-                    (window-min-size window nil window pixelwise))))
-            (max-height
-             ;; Sanitize MAX-HEIGHT.
-             (if (numberp max-height)
-                 (min
-                  (+ total-height
-                     (window-max-delta
-                      window nil window nil t nil pixelwise))
-                  (if pixelwise
-                      (* char-height max-height)
-                    max-height))
-               (+ total-height (window-max-delta
-                                window nil window nil t nil pixelwise))))
-            height)
-       (cond
-        ;; If WINDOW is vertically combined, try to resize it
-        ;; vertically.
-        ((and (not (eq fit-window-to-buffer-horizontally 'only))
-              (not (window-size-fixed-p window 'preserved))
-              (window-combined-p))
+    (let* ((pixelwise window-resize-pixelwise)
+           (frame (window-frame window))
+           (char-height (frame-char-height frame)))
+      (cond
+       ;; If WINDOW is vertically combined, try to resize it
+       ;; vertically.
+       ((and (not (eq fit-window-to-buffer-horizontally 'only))
+            (not (window-size-fixed-p window 'preserved))
+            (window-combined-p))
+        (let* ((line-height (window-default-line-height window))
+              (total-height (window-size window nil pixelwise))
+               (min-height
+               ;; Sanitize MIN-HEIGHT.
+               (if (numberp min-height)
+                   ;; Can't get smaller than `window-safe-min-height'.
+                   (max (if pixelwise
+                            (* line-height min-height)
+                          min-height)
+                        (if pixelwise
+                            (window-safe-min-pixel-height window)
+                          window-safe-min-height))
+                 ;; Preserve header and mode line if present.
+                 (max (if pixelwise
+                          (* line-height window-min-height)
+                        window-min-height)
+                      (window-min-size window nil window pixelwise))))
+              (max-height
+               ;; Sanitize MAX-HEIGHT.
+               (if (numberp max-height)
+                   (min
+                    (+ total-height
+                       (window-max-delta
+                        window nil window nil t nil pixelwise))
+                    (if pixelwise
+                        (* line-height max-height)
+                      (/ (* line-height max-height) line-height)))
+                 (+ total-height (window-max-delta
+                                  window nil window nil t nil pixelwise))))
+              (height (+ (cdr (window-text-pixel-size
+                               window nil t nil (frame-pixel-height frame) t))
+                         (window-scroll-bar-height window)
+                         (window-bottom-divider-width window))))
          ;; Vertically we always want to fit the entire buffer.
          ;; WINDOW'S height can't get larger than its frame's pixel
          ;; height.  Its width remains fixed.
-         (setq height (+ (cdr (window-text-pixel-size
-                               nil nil t nil (frame-pixel-height) t))
-                         (window-scroll-bar-height window)
-                         (window-bottom-divider-width)))
          ;; Round height.
          (unless pixelwise
            (setq height (/ (+ height char-height -1) char-height)))
+          (setq height (max min-height (min max-height height)))
          (unless (= height total-height)
            (window-preserve-size window)
            (window-resize-no-error
-            window
-            (- (max min-height (min max-height height)) total-height)
-            nil window pixelwise)
+            window (- height total-height) nil window pixelwise)
            (when preserve-size
-             (window-preserve-size window nil t))))
-        ;; If WINDOW is horizontally combined, try to resize it
-        ;; horizontally.
-        ((and fit-window-to-buffer-horizontally
-              (not (window-size-fixed-p window t 'preserved))
-              (window-combined-p nil t))
-         (let* ((total-width (window-size window t pixelwise))
-                (min-width
-                 ;; Sanitize MIN-WIDTH.
-                 (if (numberp min-width)
-                     ;; Can't get smaller than `window-safe-min-width'.
-                     (max (if pixelwise
-                              (* char-width min-width)
-                            min-width)
-                          (if pixelwise
-                              (window-safe-min-pixel-width)
-                            window-safe-min-width))
-                   ;; Preserve fringes, margins, scrollbars if present.
+             (window-preserve-size window nil t)))))
+       ;; If WINDOW is horizontally combined, try to resize it
+       ;; horizontally.
+       ((and fit-window-to-buffer-horizontally
+            (not (window-size-fixed-p window t 'preserved))
+            (window-combined-p window t))
+       (let* ((char-width (frame-char-width frame))
+               (total-width (window-size window t pixelwise))
+              (min-width
+               ;; Sanitize MIN-WIDTH.
+               (if (numberp min-width)
+                   ;; Can't get smaller than `window-safe-min-width'.
                    (max (if pixelwise
-                            (* char-width window-min-width)
-                          window-min-width)
-                        (window-min-size nil nil window pixelwise))))
-                (max-width
-                 ;; Sanitize MAX-WIDTH.
-                 (if (numberp max-width)
-                     (min (+ total-width
-                             (window-max-delta
-                              window t window nil t nil pixelwise))
-                          (if pixelwise
-                              (* char-width max-width)
-                            max-width))
-                   (+ total-width (window-max-delta
-                                   window t window nil t nil pixelwise))))
-                ;; When fitting horizontally, assume that WINDOW's
-                ;; start position remains unaltered.  WINDOW can't get
-                ;; wider than its frame's pixel width, its height
-                ;; remains unaltered.
-                (width (+ (car (window-text-pixel-size
-                                nil (window-start) (point-max)
-                                (frame-pixel-width)
-                                ;; Add one char-height to assure that
-                                ;; we're on the safe side.  This
-                                ;; overshoots when the first line below
-                                ;; the bottom is wider than the window.
-                                (* body-height
-                                   (if pixelwise 1 char-height))))
-                          (window-right-divider-width))))
-           (unless pixelwise
-             (setq width (/ (+ width char-width -1) char-width)))
-           (unless (= width body-width)
-             (window-preserve-size window t)
-             (window-resize-no-error
-              window
-              (- (max min-width
-                      (min max-width
-                           (+ total-width (- width body-width))))
-                 total-width)
-              t window pixelwise)
-             (when preserve-size
-               (window-preserve-size window t t))))))))))
+                            (* char-width min-width)
+                          min-width)
+                        (if pixelwise
+                            (window-safe-min-pixel-width window)
+                          window-safe-min-width))
+                 ;; Preserve fringes, margins, scrollbars if present.
+                 (max (if pixelwise
+                          (* char-width window-min-width)
+                        window-min-width)
+                      (window-min-size window nil window pixelwise))))
+              (max-width
+               ;; Sanitize MAX-WIDTH.
+               (if (numberp max-width)
+                   (min (+ total-width
+                           (window-max-delta
+                            window t window nil t nil pixelwise))
+                        (if pixelwise
+                            (* char-width max-width)
+                          max-width))
+                 (+ total-width (window-max-delta
+                                 window t window nil t nil pixelwise))))
+              ;; When fitting horizontally, assume that WINDOW's
+              ;; start position remains unaltered.  WINDOW can't get
+              ;; wider than its frame's pixel width, its height
+              ;; remains unaltered.
+              (width (+ (car (window-text-pixel-size
+                              window (window-start) (point-max)
+                              (frame-pixel-width)
+                              ;; Add one line-height to assure that
+                              ;; we're on the safe side.  This
+                              ;; overshoots when the first line below
+                              ;; the bottom is wider than the window.
+                              (* (window-body-height window pixelwise)
+                                 (if pixelwise 1 char-height))))
+                         (- total-width
+                            (window-body-width window pixelwise)))))
+         (unless pixelwise
+           (setq width (/ (+ width char-width -1) char-width)))
+          (setq width (max min-width (min max-width width)))
+         (unless (= width total-width)
+           (window-preserve-size window t)
+           (window-resize-no-error
+             window (- width total-width) t window pixelwise)
+           (when preserve-size
+             (window-preserve-size window t t)))))))))
 
 (defun window-safely-shrinkable-p (&optional window)
   "Return t if WINDOW can be shrunk without shrinking other windows.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]