mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-15 10:30:25 -08:00
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.
This commit is contained in:
parent
fcfe6e2797
commit
e3f97d7365
1 changed files with 141 additions and 111 deletions
252
lisp/window.el
252
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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue