summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog36
-rw-r--r--lisp/frame.el77
-rw-r--r--lisp/menu-bar.el36
-rw-r--r--lisp/scroll-bar.el236
-rw-r--r--lisp/startup.el15
-rw-r--r--lisp/window.el104
6 files changed, 363 insertions, 141 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 454dc823ef7..3f97396ca02 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,39 @@
+2014-07-27 Martin Rudalics <rudalics@gmx.at>
+
+ * frame.el (frame-notice-user-settings): Rewrite using
+ frame-initial-frame-tool-bar-height.
+ * menu-bar.el (menu-bar-horizontal-scroll-bar)
+ (menu-bar-no-horizontal-scroll-bar): New functions.
+ (menu-bar-showhide-scroll-bar-menu): Add bindings for horizontal
+ scroll bars.
+ * scroll-bar.el (scroll-bar-lines)
+ (set-horizontal-scroll-bar-mode)
+ (get-horizontal-scroll-bar-mode, horizontal-scroll-bar-mode)
+ (scroll-bar-horizontal-drag-1, scroll-bar-horizontal-drag)
+ (scroll-bar-toolkit-horizontal-scroll): New functions.
+ (horizontal-scroll-bar-mode)
+ (previous-horizontal-scroll-bar-mode)
+ (horizontal-scroll-bar-mode-explicit): New variables.
+ (horizontal-scroll-bar-mode): New option.
+ (toggle-horizontal-scroll-bar): Do something.
+ (top-level): Bind horizontal-scroll-bar mouse-1.
+ * startup.el (tool-bar-originally-present): Remove variable.
+ (command-line): Don't set tool-bar-originally-present.
+ * window.el (window-min-height): Update doc-string.
+ (window--dump-frame): Dump horizontal scroll bar values.
+ (window--min-size-1): Handle minibuffer window separately.
+ Count in margins and horizontal scroll bar. Return safe value
+ iff IGNORE equals 'safe.
+ (frame-windows-min-size): New function (used by frame resizing
+ routines).
+ (fit-frame-to-buffer, fit-window-to-buffer): Count in horizontal
+ scroll bars.
+ (window--sanitize-window-sizes): New function.
+ (window-split-min-size): Remove.
+ (split-window): Count divider-width. Don't use
+ `window-split-min-size' any more. Reword error messages.
+ Sanitize windows sizes after splitting.
+
2014-07-27 Thien-Thi Nguyen <ttn@gnu.org>
Use `defvar-local' more.
diff --git a/lisp/frame.el b/lisp/frame.el
index 9a170134e3d..d3e84d21024 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -256,60 +256,43 @@ there (in decreasing order of priority)."
;; If the initial frame is still around, apply initial-frame-alist
;; and default-frame-alist to it.
(when (frame-live-p frame-initial-frame)
-
;; When tool-bar has been switched off, correct the frame size
;; by the lines added in x-create-frame for the tool-bar and
;; switch `tool-bar-mode' off.
(when (display-graphic-p)
- (let ((tool-bar-lines (or (assq 'tool-bar-lines initial-frame-alist)
- (assq 'tool-bar-lines window-system-frame-alist)
- (assq 'tool-bar-lines default-frame-alist))))
- (when (and tool-bar-originally-present
- (or (null tool-bar-lines)
- (null (cdr tool-bar-lines))
- (eq 0 (cdr tool-bar-lines))))
- (let* ((char-height (frame-char-height frame-initial-frame))
- (image-height tool-bar-images-pixel-height)
- (margin (cond ((and (consp tool-bar-button-margin)
- (integerp (cdr tool-bar-button-margin))
- (> tool-bar-button-margin 0))
- (cdr tool-bar-button-margin))
- ((and (integerp tool-bar-button-margin)
- (> tool-bar-button-margin 0))
- tool-bar-button-margin)
- (t 0)))
- (relief (if (and (integerp tool-bar-button-relief)
- (> tool-bar-button-relief 0))
- tool-bar-button-relief 3))
- (lines (/ (+ image-height
- (* 2 margin)
- (* 2 relief)
- (1- char-height))
- char-height))
- (height (frame-parameter frame-initial-frame 'height))
- (newparms (list (cons 'height (- height lines))))
- (initial-top (cdr (assq 'top
- frame-initial-geometry-arguments)))
+ (let ((tool-bar-lines
+ (or (assq 'tool-bar-lines initial-frame-alist)
+ (assq 'tool-bar-lines window-system-frame-alist)
+ (assq 'tool-bar-lines default-frame-alist))))
+ ;; Shrink frame by its initial tool bar height iff either zero
+ ;; tool bar lines have been requested in one of the frame's
+ ;; alists or tool bar mode has been turned off explicitly in
+ ;; the user's init file.
+ (when (and tool-bar-lines
+ (> frame-initial-frame-tool-bar-height 0)
+ (or (not tool-bar-mode)
+ (null (cdr tool-bar-lines))
+ (eq 0 (cdr tool-bar-lines))))
+ (set-frame-height
+ frame-initial-frame (- (frame-text-height frame-initial-frame)
+ frame-initial-frame-tool-bar-height)
+ nil t)
+ (let* ((initial-top
+ (cdr (assq 'top frame-initial-geometry-arguments)))
(top (frame-parameter frame-initial-frame 'top)))
(when (and (consp initial-top) (eq '- (car initial-top)))
(let ((adjusted-top
- (cond ((and (consp top)
- (eq '+ (car top)))
- (list '+
- (+ (cadr top)
- (* lines char-height))))
- ((and (consp top)
- (eq '- (car top)))
- (list '-
- (- (cadr top)
- (* lines char-height))))
- (t (+ top (* lines char-height))))))
- (setq newparms
- (append newparms
- `((top . ,adjusted-top))
- nil))))
- (modify-frame-parameters frame-initial-frame newparms)
- (tool-bar-mode -1)))))
+ (cond
+ ((and (consp top) (eq '+ (car top)))
+ (list '+ (+ (cadr top)
+ frame-initial-frame-tool-bar-height)))
+ ((and (consp top) (eq '- (car top)))
+ (list '- (- (cadr top)
+ frame-initial-frame-tool-bar-height)))
+ (t (+ top frame-initial-frame-tool-bar-height)))))
+ (modify-frame-parameters
+ frame-initial-frame '((top . adjusted-top))))))
+ (tool-bar-mode -1))))
;; The initial frame we create above always has a minibuffer.
;; If the user wants to remove it, or make it a minibuffer-only
diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el
index c816488c6d1..5ad4bed49b8 100644
--- a/lisp/menu-bar.el
+++ b/lisp/menu-bar.el
@@ -887,8 +887,35 @@ by \"Save Options\" in Custom buffers.")
(interactive)
(customize-set-variable 'scroll-bar-mode nil))
+(defun menu-bar-horizontal-scroll-bar ()
+ "Display horizontal scroll bars on each window."
+ (interactive)
+ (customize-set-variable 'horizontal-scroll-bar-mode t))
+
+(defun menu-bar-no-horizontal-scroll-bar ()
+ "Turn off horizontal scroll bars."
+ (interactive)
+ (customize-set-variable 'horizontal-scroll-bar-mode nil))
+
(defvar menu-bar-showhide-scroll-bar-menu
(let ((menu (make-sparse-keymap "Scroll-bar")))
+ (bindings--define-key menu [horizontal]
+ '(menu-item "Horizontal"
+ menu-bar-horizontal-scroll-bar
+ :help "Horizontal scroll bar"
+ :visible (display-graphic-p)
+ :button (:radio . (eq (cdr (assq 'horizontal-scroll-bars
+ (frame-parameters)))
+ t))))
+
+ (bindings--define-key menu [none-horizontal]
+ '(menu-item "None-horizontal"
+ menu-bar-no-horizontal-scroll-bar
+ :help "Turn off horizontal scroll bars"
+ :visible (display-graphic-p)
+ :button (:radio . (eq (cdr (assq 'horizontal-scroll-bars
+ (frame-parameters)))
+ nil))))
(bindings--define-key menu [right]
'(menu-item "On the Right"
@@ -896,7 +923,8 @@ by \"Save Options\" in Custom buffers.")
:help "Scroll-bar on the right side"
:visible (display-graphic-p)
:button (:radio . (eq (cdr (assq 'vertical-scroll-bars
- (frame-parameters))) 'right))))
+ (frame-parameters)))
+ 'right))))
(bindings--define-key menu [left]
'(menu-item "On the Left"
@@ -904,7 +932,8 @@ by \"Save Options\" in Custom buffers.")
:help "Scroll-bar on the left side"
:visible (display-graphic-p)
:button (:radio . (eq (cdr (assq 'vertical-scroll-bars
- (frame-parameters))) 'left))))
+ (frame-parameters)))
+ 'left))))
(bindings--define-key menu [none]
'(menu-item "None"
@@ -912,7 +941,8 @@ by \"Save Options\" in Custom buffers.")
:help "Turn off scroll-bar"
:visible (display-graphic-p)
:button (:radio . (eq (cdr (assq 'vertical-scroll-bars
- (frame-parameters))) nil))))
+ (frame-parameters)))
+ nil))))
menu))
(defun menu-bar-frame-for-menubar ()
diff --git a/lisp/scroll-bar.el b/lisp/scroll-bar.el
index 2990e8e5ffa..09f30d5d3f0 100644
--- a/lisp/scroll-bar.el
+++ b/lisp/scroll-bar.el
@@ -70,16 +70,36 @@ SIDE must be the symbol `left' or `right'."
(frame-char-width)))
(0))))
+(defun scroll-bar-lines ()
+ "Return the height, measured in lines, of the horizontal scrollbar."
+ (let* ((wsb (window-scroll-bars))
+ (htype (nth 5 wsb))
+ (lines (nth 4 wsb)))
+ (cond
+ (htype lines)
+ ((frame-parameter nil 'horizontal-scroll-bars)
+ ;; nil means it's a non-toolkit scroll bar (which is currently
+ ;; impossible), and its width in columns is 14 pixels rounded up.
+ (ceiling (or (frame-parameter nil 'scroll-bar-height) 14)
+ (frame-char-width)))
+ (0))))
+
;;;; Helpful functions for enabling and disabling scroll bars.
(defvar scroll-bar-mode)
+(defvar horizontal-scroll-bar-mode)
(defvar previous-scroll-bar-mode nil)
+(defvar previous-horizontal-scroll-bar-mode nil)
(defvar scroll-bar-mode-explicit nil
"Non-nil means `set-scroll-bar-mode' should really do something.
This is nil while loading `scroll-bar.el', and t afterward.")
+(defvar horizontal-scroll-bar-mode-explicit nil
+ "Non-nil means `set-horizontal-scroll-bar-mode' should really do something.
+This is nil while loading `scroll-bar.el', and t afterward.")
+
(defun set-scroll-bar-mode (value)
"Set the scroll bar mode to VALUE and put the new value into effect.
See the `scroll-bar-mode' variable for possible values to use."
@@ -92,6 +112,18 @@ See the `scroll-bar-mode' variable for possible values to use."
(modify-all-frames-parameters (list (cons 'vertical-scroll-bars
scroll-bar-mode)))))
+(defun set-horizontal-scroll-bar-mode (value)
+ "Set the horizontal scroll bar mode to VALUE and put the new value into effect.
+See the `horizontal-scroll-bar-mode' variable for possible values to use."
+ (if horizontal-scroll-bar-mode
+ (setq previous-horizontal-scroll-bar-mode horizontal-scroll-bar-mode))
+
+ (setq horizontal-scroll-bar-mode value)
+
+ (when horizontal-scroll-bar-mode-explicit
+ (modify-all-frames-parameters (list (cons 'horizontal-scroll-bars
+ horizontal-scroll-bar-mode)))))
+
(defcustom scroll-bar-mode default-frame-scroll-bars
"Specify whether to have vertical scroll bars, and on which side.
Possible values are nil (no scroll bars), `left' (scroll bars on left)
@@ -108,14 +140,32 @@ Setting the variable with a customization buffer also takes effect."
:initialize 'custom-initialize-default
:set (lambda (_sym val) (set-scroll-bar-mode val)))
+(defcustom horizontal-scroll-bar-mode default-frame-horizontal-scroll-bars
+ "Specify whether to have horizontal scroll bars, and on which side.
+To set this variable in a Lisp program, use `set-horizontal-scroll-bar-mode'
+to make it take real effect.
+Setting the variable with a customization buffer also takes effect."
+ :type '(choice (const :tag "none (nil)" nil)
+ (const t))
+ :group 'frames
+ ;; The default value for :initialize would try to use :set
+ ;; when processing the file in cus-dep.el.
+ :initialize 'custom-initialize-default
+ :set (lambda (_sym val) (set-horizontal-scroll-bar-mode val)))
+
;; We just set scroll-bar-mode, but that was the default.
;; If it is set again, that is for real.
(setq scroll-bar-mode-explicit t)
+(setq horizontal-scroll-bar-mode-explicit t)
(defun get-scroll-bar-mode ()
(declare (gv-setter set-scroll-bar-mode))
scroll-bar-mode)
+(defun get-horizontal-scroll-bar-mode ()
+ (declare (gv-setter set-horizontal-scroll-bar-mode))
+ horizontal-scroll-bar-mode)
+
(define-minor-mode scroll-bar-mode
"Toggle vertical scroll bars on all frames (Scroll Bar mode).
With a prefix argument ARG, enable Scroll Bar mode if ARG is
@@ -126,8 +176,21 @@ This command applies to all frames that exist and frames to be
created in the future."
:variable ((get-scroll-bar-mode)
. (lambda (v) (set-scroll-bar-mode
- (if v (or previous-scroll-bar-mode
- default-frame-scroll-bars))))))
+ (if v (or previous-scroll-bar-mode
+ default-frame-scroll-bars))))))
+
+(define-minor-mode horizontal-scroll-bar-mode
+ "Toggle horizontal scroll bars on all frames (Horizontal Scroll Bar mode).
+With a prefix argument ARG, enable Horizontal Scroll Bar mode if
+ARG is positive, and disable it otherwise. If called from Lisp,
+enable the mode if ARG is omitted or nil.
+
+This command applies to all frames that exist and frames to be
+created in the future."
+ :variable ((get-horizontal-scroll-bar-mode)
+ . (lambda (v) (set-horizontal-scroll-bar-mode
+ (if v (or previous-scroll-bar-mode
+ default-frame-horizontal-scroll-bars))))))
(defun toggle-scroll-bar (arg)
"Toggle whether or not the selected frame has vertical scroll bars.
@@ -147,12 +210,21 @@ when they are turned on; if it is nil, they go on the left."
(if (> arg 0)
(or scroll-bar-mode default-frame-scroll-bars))))))
-(defun toggle-horizontal-scroll-bar (_arg)
+(defun toggle-horizontal-scroll-bar (arg)
"Toggle whether or not the selected frame has horizontal scroll bars.
-With arg, turn horizontal scroll bars on if and only if arg is positive.
-Horizontal scroll bars aren't implemented yet."
+With arg, turn horizontal scroll bars on if and only if arg is positive."
(interactive "P")
- (error "Horizontal scroll bars aren't implemented yet"))
+ (if (null arg)
+ (setq arg
+ (if (cdr (assq 'horizontal-scroll-bars
+ (frame-parameters (selected-frame))))
+ -1 1))
+ (setq arg (prefix-numeric-value arg)))
+ (modify-frame-parameters
+ (selected-frame)
+ (list (cons 'horizontal-scroll-bars
+ (if (> arg 0)
+ (or horizontal-scroll-bar-mode default-frame-horizontal-scroll-bars))))))
;;;; Buffer navigation using the scroll bar.
@@ -249,6 +321,45 @@ If you click outside the slider, the window scrolls to bring the slider there."
(with-current-buffer (window-buffer window)
(setq point-before-scroll before-scroll))))
+;; Scroll the window to the proper position for EVENT.
+(defun scroll-bar-horizontal-drag-1 (event)
+ (let* ((start-position (event-start event))
+ (window (nth 0 start-position))
+ (portion-whole (nth 2 start-position))
+ (unit (frame-char-width (window-frame window))))
+ (set-window-hscroll
+ window (/ (1- (+ (car portion-whole) unit)) unit))))
+
+(defun scroll-bar-horizontal-drag (event)
+ "Scroll the window horizontally by dragging the scroll bar slider.
+If you click outside the slider, the window scrolls to bring the slider there."
+ (interactive "e")
+ (let* (done
+ (echo-keystrokes 0)
+ (end-position (event-end event))
+ (window (nth 0 end-position))
+ (before-scroll))
+ (with-current-buffer (window-buffer window)
+ (setq before-scroll point-before-scroll))
+ (save-selected-window
+ (select-window window)
+ (setq before-scroll
+ (or before-scroll (point))))
+ (scroll-bar-horizontal-drag-1 event)
+ (track-mouse
+ (while (not done)
+ (setq event (read-event))
+ (if (eq (car-safe event) 'mouse-movement)
+ (setq event (read-event)))
+ (cond ((eq (car-safe event) 'scroll-bar-movement)
+ (scroll-bar-horizontal-drag-1 event))
+ (t
+ ;; Exit when we get the drag event; ignore that event.
+ (setq done t)))))
+ (sit-for 0)
+ (with-current-buffer (window-buffer window)
+ (setq point-before-scroll before-scroll))))
+
(defun scroll-bar-scroll-down (event)
"Scroll the window's top line down to the location of the scroll bar click.
EVENT should be a scroll bar click."
@@ -300,47 +411,92 @@ EVENT should be a scroll bar click."
(window (nth 0 end-position))
(part (nth 4 end-position))
before-scroll)
- (cond ((eq part 'end-scroll))
- (t
- (with-current-buffer (window-buffer window)
- (setq before-scroll point-before-scroll))
- (save-selected-window
- (select-window window)
- (setq before-scroll (or before-scroll (point)))
- (cond ((eq part 'above-handle)
- (scroll-up '-))
- ((eq part 'below-handle)
- (scroll-up nil))
- ((eq part 'ratio)
- (let* ((portion-whole (nth 2 end-position))
- (lines (scroll-bar-scale portion-whole
- (1- (window-height)))))
- (scroll-up (cond ((not (zerop lines)) lines)
- ((< (car portion-whole) 0) -1)
- (t 1)))))
- ((eq part 'up)
- (scroll-up -1))
- ((eq part 'down)
- (scroll-up 1))
- ((eq part 'top)
- (set-window-start window (point-min)))
- ((eq part 'bottom)
- (goto-char (point-max))
- (recenter))
- ((eq part 'handle)
- (scroll-bar-drag-1 event))))
- (sit-for 0)
- (with-current-buffer (window-buffer window)
- (setq point-before-scroll before-scroll))))))
-
+ (cond
+ ((eq part 'end-scroll))
+ (t
+ (with-current-buffer (window-buffer window)
+ (setq before-scroll point-before-scroll))
+ (save-selected-window
+ (select-window window)
+ (setq before-scroll (or before-scroll (point)))
+ (cond
+ ((eq part 'above-handle)
+ (scroll-up '-))
+ ((eq part 'below-handle)
+ (scroll-up nil))
+ ((eq part 'ratio)
+ (let* ((portion-whole (nth 2 end-position))
+ (lines (scroll-bar-scale portion-whole
+ (1- (window-height)))))
+ (scroll-up (cond ((not (zerop lines)) lines)
+ ((< (car portion-whole) 0) -1)
+ (t 1)))))
+ ((eq part 'up)
+ (scroll-up -1))
+ ((eq part 'down)
+ (scroll-up 1))
+ ((eq part 'top)
+ (set-window-start window (point-min)))
+ ((eq part 'bottom)
+ (goto-char (point-max))
+ (recenter))
+ ((eq part 'handle)
+ (scroll-bar-drag-1 event))))
+ (sit-for 0)
+ (with-current-buffer (window-buffer window)
+ (setq point-before-scroll before-scroll))))))
+(defun scroll-bar-toolkit-horizontal-scroll (event)
+ (interactive "e")
+ (let* ((end-position (event-end event))
+ (window (nth 0 end-position))
+ (part (nth 4 end-position))
+ before-scroll)
+ (cond
+ ((eq part 'end-scroll))
+ (t
+ (with-current-buffer (window-buffer window)
+ (setq before-scroll point-before-scroll))
+ (save-selected-window
+ (select-window window)
+ (setq before-scroll (or before-scroll (point)))
+ (cond
+ ((eq part 'before-handle)
+ (scroll-right 4))
+ ((eq part 'after-handle)
+ (scroll-left 4))
+ ((eq part 'ratio)
+ (let* ((portion-whole (nth 2 end-position))
+ (columns (scroll-bar-scale portion-whole
+ (1- (window-width)))))
+ (scroll-right
+ (cond
+ ((not (zerop columns))
+ columns)
+ ((< (car portion-whole) 0) -1)
+ (t 1)))))
+ ((eq part 'left)
+ (scroll-right 1))
+ ((eq part 'right)
+ (scroll-left 1))
+ ((eq part 'leftmost)
+ (goto-char (line-beginning-position)))
+ ((eq part 'rightmost)
+ (goto-char (line-end-position)))
+ ((eq part 'horizontal-handle)
+ (scroll-bar-horizontal-drag-1 event))))
+ (sit-for 0)
+ (with-current-buffer (window-buffer window)
+ (setq point-before-scroll before-scroll))))))
;;;; Bindings.
;; For now, we'll set things up to work like xterm.
(cond ((and (boundp 'x-toolkit-scroll-bars) x-toolkit-scroll-bars)
(global-set-key [vertical-scroll-bar mouse-1]
- 'scroll-bar-toolkit-scroll))
+ 'scroll-bar-toolkit-scroll)
+ (global-set-key [horizontal-scroll-bar mouse-1]
+ 'scroll-bar-toolkit-horizontal-scroll))
(t
(global-set-key [vertical-scroll-bar mouse-1]
'scroll-bar-scroll-up)
diff --git a/lisp/startup.el b/lisp/startup.el
index d984e6269ae..144d732272f 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -719,9 +719,6 @@ It is the default value of the variable `top-level'."
(defconst tool-bar-images-pixel-height 24
"Height in pixels of images in the tool-bar.")
-(defvar tool-bar-originally-present nil
- "Non-nil if tool-bars are present before user and site init files are read.")
-
(defvar handle-args-function-alist '((nil . tty-handle-args))
"Functions for processing window-system dependent command-line arguments.
Window system startup files should add their own function to this
@@ -1042,18 +1039,6 @@ please check its value")
(or (eq initial-window-system 'pc)
(tty-register-default-colors))
- ;; Record whether the tool-bar is present before the user and site
- ;; init files are processed. frame-notice-user-settings uses this
- ;; to determine if the tool-bar has been disabled by the init files,
- ;; and the frame needs to be resized.
- (when (fboundp 'frame-notice-user-settings)
- (let ((tool-bar-lines (or (assq 'tool-bar-lines initial-frame-alist)
- (assq 'tool-bar-lines default-frame-alist))))
- (setq tool-bar-originally-present
- (and tool-bar-lines
- (cdr tool-bar-lines)
- (not (eq 0 (cdr tool-bar-lines)))))))
-
(let ((old-scalable-fonts-allowed scalable-fonts-allowed)
(old-face-ignored-fonts face-ignored-fonts))
diff --git a/lisp/window.el b/lisp/window.el
index e1c79659773..a7dcd9a6612 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -378,9 +378,9 @@ Anything less might crash Emacs.")
(defcustom window-min-height 4
"The minimum total height, in lines, of any window.
The value has to accommodate one text line, a mode and header
-line, and a bottom divider, if present. A value less than
-`window-safe-min-height' is ignored. The value of this variable
-is honored when windows are resized or split.
+line, a horizontal scroll bar and a bottom divider, if present.
+A value less than `window-safe-min-height' is ignored. The value
+of this variable is honored when windows are resized or split.
Applications should never rebind this variable. To resize a
window to a height less than the one specified here, an
@@ -1137,11 +1137,12 @@ dumping to it."
(format "frame text pixel: %s x %s cols/lines: %s x %s\n"
(frame-text-width frame) (frame-text-height frame)
(frame-text-cols frame) (frame-text-lines frame))
- (format "tool: %s scroll: %s fringe: %s border: %s right: %s bottom: %s\n\n"
+ (format "tool: %s scroll: %s/%s fringe: %s border: %s right: %s bottom: %s\n\n"
(if (fboundp 'tool-bar-height)
(tool-bar-height frame t)
"0")
(frame-scroll-bar-width frame)
+ (frame-scroll-bar-height frame)
(frame-fringe-width frame)
(frame-border-width frame)
(frame-right-divider-width frame)
@@ -1262,12 +1263,14 @@ of WINDOW."
value)
(with-current-buffer (window-buffer window)
(cond
+ ((window-minibuffer-p window)
+ (if pixelwise (frame-char-height (window-frame window)) 1))
((and (not (window--size-ignore-p window ignore))
(window-size-fixed-p window horizontal))
;; The minimum size of a fixed size window is its size.
(window-size window horizontal pixelwise))
- ((or (eq ignore 'safe) (eq ignore window))
- ;; If IGNORE equals `safe' or WINDOW return the safe values.
+ ((eq ignore 'safe)
+ ;; If IGNORE equals `safe' return the safe value.
(window-safe-min-size window horizontal pixelwise))
(horizontal
;; For the minimum width of a window take fringes and
@@ -1278,8 +1281,11 @@ of WINDOW."
;; `window-min-width'.
(let* ((char-size (frame-char-size window t))
(fringes (window-fringes window))
+ (margins (window-margins window))
(pixel-width
(+ (window-safe-min-size window t t)
+ (* (or (car margins) 0) char-size)
+ (* (or (cdr margins) 0) char-size)
(car fringes) (cadr fringes)
(window-scroll-bar-width window)
(window-right-divider-width window))))
@@ -1301,6 +1307,7 @@ of WINDOW."
(pixel-height
(+ (window-safe-min-size window nil t)
(window-header-line-height window)
+ (window-scroll-bar-height window)
(window-mode-line-height window)
(window-bottom-divider-width window))))
(if pixelwise
@@ -1508,6 +1515,18 @@ by which WINDOW can be shrunk."
(window--min-delta-1
window (- size minimum) horizontal ignore trail noup pixelwise)))))
+(defun frame-windows-min-size (&optional frame horizontal pixelwise)
+ "Return minimum number of lines of FRAME's windows.
+HORIZONTAL non-nil means return number of columns of FRAME's
+windows. PIXELWISE non-nil means return sizes in pixels."
+ (setq frame (window-normalize-frame frame))
+ (let* ((root (frame-root-window frame))
+ (mini (window-next-sibling root)))
+ (+ (window-min-size root horizontal nil pixelwise)
+ (if (and mini (not horizontal))
+ (window-min-size mini horizontal nil pixelwise)
+ 0))))
+
(defun window--max-delta-1 (window delta &optional horizontal ignore trail noup pixelwise)
"Internal function of `window-max-delta'."
(if (not (window-parent window))
@@ -2984,6 +3003,28 @@ routines."
pixel-delta
(/ pixel-delta (frame-char-height frame)))))
+(defun window--sanitize-window-sizes (frame horizontal)
+ "Assert that all windows on FRAME are large enough.
+If necessary and possible, make sure that every window on frame
+FRAME has its minimum height. Optional argument HORIZONTAL
+non-nil means to make sure that every window on frame FRAME has
+its minimum width. The minimumm height/width of a window is the
+respective value returned by `window-min-size' for that window.
+
+Return t if all windows were resized appropriately. Return nil
+if at least one window could not be resized as requested, which
+may happen when the FRAME is not large enough to accomodate it."
+ (let ((value t))
+ (walk-window-tree
+ (lambda (window)
+ (let ((delta (- (window-min-size window horizontal nil t)
+ (window-size window horizontal t))))
+ (when (> delta 0)
+ (if (window-resizable-p window delta horizontal nil t)
+ (window-resize window delta horizontal nil t)
+ (setq value nil))))))
+ value))
+
(defun adjust-window-trailing-edge (window delta &optional horizontal pixelwise)
"Move WINDOW's bottom edge by DELTA lines.
Optional argument HORIZONTAL non-nil means move WINDOW's right
@@ -4241,20 +4282,6 @@ showing BUFFER-OR-NAME."
;; If a window doesn't show BUFFER, unrecord BUFFER in it.
(unrecord-window-buffer window buffer)))))
-;;; Splitting windows.
-(defun window-split-min-size (&optional horizontal pixelwise)
- "Return minimum height of any window when splitting windows.
-Optional argument HORIZONTAL non-nil means return minimum width."
- (cond
- (pixelwise
- (if horizontal
- (window-min-pixel-width)
- (window-min-pixel-height)))
- (horizontal
- (max window-min-width window-safe-min-width))
- (t
- (max window-min-height window-safe-min-height))))
-
(defun split-window (&optional window size side pixelwise)
"Make a new window adjacent to WINDOW.
WINDOW must be a valid window and defaults to the selected one.
@@ -4318,6 +4345,9 @@ frame. The selected window is not changed by this function."
(pixel-size
(when (numberp size)
(window--size-to-pixel window size horizontal pixelwise t)))
+ (divider-width (if horizontal
+ (frame-right-divider-width frame)
+ (frame-bottom-divider-width frame)))
atom-root)
(window--check frame)
(catch 'done
@@ -4419,19 +4449,14 @@ frame. The selected window is not changed by this function."
(cond
(resize
;; SIZE unspecified, resizing.
- (when (and (not (window-sizable-p
- parent (- new-pixel-size) horizontal nil t))
- ;; Try again with minimum split size.
- (setq new-pixel-size
- (max new-pixel-size
- (window-split-min-size horizontal t)))
- (not (window-sizable-p
- parent (- new-pixel-size) horizontal nil t)))
- (error "Window %s too small for splitting 1" parent)))
- ((> (+ new-pixel-size (window-min-size window horizontal nil t))
+ (unless (window-sizable-p
+ parent (- new-pixel-size divider-width) horizontal nil t)
+ (error "Window %s too small for splitting (1)" parent)))
+ ((> (+ new-pixel-size divider-width
+ (window-min-size window horizontal nil t))
old-pixel-size)
;; SIZE unspecified, no resizing.
- (error "Window %s too small for splitting 2" window))))
+ (error "Window %s too small for splitting (2)" window))))
((and (>= pixel-size 0)
(or (>= pixel-size old-pixel-size)
(< new-pixel-size
@@ -4439,19 +4464,19 @@ frame. The selected window is not changed by this function."
;; SIZE specified as new size of old window. If the new size
;; is larger than the old size or the size of the new window
;; would be less than the safe minimum, signal an error.
- (error "Window %s too small for splitting 3" window))
+ (error "Window %s too small for splitting (3)" window))
(resize
;; SIZE specified, resizing.
(unless (window-sizable-p
- parent (- new-pixel-size) horizontal nil t)
+ parent (- new-pixel-size divider-width) horizontal nil t)
;; If we cannot resize the parent give up.
- (error "Window %s too small for splitting 4" parent)))
+ (error "Window %s too small for splitting (4)" parent)))
((or (< new-pixel-size
(window-safe-min-pixel-size window horizontal))
(< (- old-pixel-size new-pixel-size)
(window-safe-min-pixel-size window horizontal)))
;; SIZE specification violates minimum size restrictions.
- (error "Window %s too small for splitting 5" window)))
+ (error "Window %s too small for splitting (5)" window)))
(window--resize-reset frame horizontal)
@@ -4522,6 +4547,9 @@ frame. The selected window is not changed by this function."
(set-window-parameter (window-parent new) 'window-atom t))
(set-window-parameter new 'window-atom t)))
+ ;; Sanitize sizes.
+ (window--sanitize-window-sizes frame horizontal)
+
(run-window-configuration-change-hook frame)
(run-window-scroll-functions new)
(window--check frame)
@@ -7116,7 +7144,10 @@ FRAME."
(value (window-text-pixel-size
nil t t workarea-width workarea-height t))
(width (+ (car value) (window-right-divider-width)))
- (height (+ (cdr value) (window-bottom-divider-width))))
+ (height
+ (+ (cdr value)
+ (window-bottom-divider-width)
+ (nth 3 (window-scroll-bars)))))
;; Don't change height or width when the window's size is fixed
;; in either direction or ONLY forbids it.
(cond
@@ -7275,6 +7306,7 @@ accessible position."
;; height. Its width remains fixed.
(setq height (+ (cdr (window-text-pixel-size
nil nil t nil (frame-pixel-height) t))
+ (nth 3 (window-scroll-bars window))
(window-bottom-divider-width)))
;; Round height.
(unless pixelwise