emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] /srv/bzr/emacs/trunk r104528: Add and rewrite window size


From: martin rudalics
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r104528: Add and rewrite window size functions in window.el.
Date: Tue, 07 Jun 2011 15:50:31 +0200
User-agent: Bazaar (2.3.1)

------------------------------------------------------------
revno: 104528
committer: martin rudalics <address@hidden>
branch nick: trunk
timestamp: Tue 2011-06-07 15:50:31 +0200
message:
  Add and rewrite window size functions in window.el.
  
  * window.el (window-safe-min-height, window-safe-min-width):
  New constants.
  (window-size-ignore, window-min-size, window-min-size-1)
  (window-sizable, window-sizable-p, window-size-fixed-1)
  (window-size-fixed-p, window-min-delta-1, window-min-delta)
  (window-max-delta-1, window-max-delta, window-resizable)
  (window-resizable-p, window-total-height, window-total-width)
  (window-body-width): New functions.
  (window-full-height-p, window-full-width-p): Rewrite using
  window-total-size.
  (window-body-height): Rewrite using window-body-size.
modified:
  lisp/ChangeLog
  lisp/window.el
=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2011-06-07 13:23:08 +0000
+++ b/lisp/ChangeLog    2011-06-07 13:50:31 +0000
@@ -5,6 +5,16 @@
        doc-strings.
        (get-buffer-window-list): Rewrite using window-list-1.  Rephrase
        doc-string.
+       (window-safe-min-height, window-safe-min-width): New constants.
+       (window-size-ignore, window-min-size, window-min-size-1)
+       (window-sizable, window-sizable-p, window-size-fixed-1)
+       (window-size-fixed-p, window-min-delta-1, window-min-delta)
+       (window-max-delta-1, window-max-delta, window-resizable)
+       (window-resizable-p, window-total-height, window-total-width)
+       (window-body-width): New functions.
+       (window-full-height-p, window-full-width-p): Rewrite using
+       window-total-size.
+       (window-body-height): Rewrite using window-body-size.
 
 2011-06-06  Martin Rudalics  <address@hidden>
 

=== modified file 'lisp/window.el'
--- a/lisp/window.el    2011-06-07 13:23:08 +0000
+++ b/lisp/window.el    2011-06-07 13:50:31 +0000
@@ -157,6 +157,14 @@
 An application may bind this to a non-nil value around calls to
 these functions to inhibit processing of window parameters.")
 
+(defconst window-safe-min-height 1
+  "The absolut minimum number of lines of a window.
+Anything less might crash Emacs.")
+
+(defconst window-safe-min-width 2
+  "The absolut minimum number of columns of a window.
+Anything less might crash Emacs.")
+
 (defun window-iso-combination-p (&optional window horizontal)
   "If WINDOW is a vertical combination return WINDOW's first child.
 WINDOW can be any window and defaults to the selected one.
@@ -491,32 +499,457 @@
 window).")
 (make-variable-buffer-local 'window-size-fixed)
 
-(defun window-body-height (&optional window)
-  "Return number of lines in WINDOW available for actual buffer text.
-WINDOW defaults to the selected window.
-
-The return value does not include the mode line or the header
+(defsubst window-size-ignore (window ignore)
+  "Return non-nil if IGNORE says to ignore size restrictions for WINDOW."
+  (if (window-any-p ignore) (eq window ignore) ignore))
+
+(defun window-min-size (&optional window horizontal ignore)
+  "Return the minimum number of lines of WINDOW.
+WINDOW can be an arbitrary window and defaults to the selected
+one.  Optional argument HORIZONTAL non-nil means return the
+minimum number of columns of WINDOW.
+
+Optional argument IGNORE non-nil means ignore any restrictions
+imposed by fixed size windows, `window-min-height' or
+`window-min-width' settings.  IGNORE equal `safe' means live
+windows may get as small as `window-safe-min-height' lines and
+`window-safe-min-width' columns.  IGNORE a window means ignore
+restrictions for that window only."
+  (window-min-size-1
+   (normalize-any-window window) horizontal ignore))
+
+(defun window-min-size-1 (window horizontal ignore)
+  "Internal function of `window-min-size'."
+  (let ((sub (window-child window)))
+    (if sub
+       (let ((value 0))
+         ;; WINDOW is an internal window.
+         (if (window-iso-combined-p sub horizontal)
+             ;; The minimum size of an iso-combination is the sum of
+             ;; the minimum sizes of its subwindows.
+             (while sub
+               (setq value (+ value
+                              (window-min-size-1 sub horizontal ignore)))
+               (setq sub (window-right sub)))
+           ;; The minimum size of an ortho-combination is the maximum of
+           ;; the minimum sizes of its subwindows.
+           (while sub
+             (setq value (max value
+                              (window-min-size-1 sub horizontal ignore)))
+             (setq sub (window-right sub))))
+         value)
+      (with-current-buffer (window-buffer window)
+       (cond
+        ((and (not (window-size-ignore window ignore))
+              (window-size-fixed-p window horizontal))
+         ;; The minimum size of a fixed size window is its size.
+         (window-total-size window horizontal))
+        ((or (eq ignore 'safe) (eq ignore window))
+         ;; If IGNORE equals `safe' or WINDOW return the safe values.
+         (if horizontal window-safe-min-width window-safe-min-height))
+        (horizontal
+         ;; For the minimum width of a window take fringes and
+         ;; scroll-bars into account.  This is questionable and should
+         ;; be removed as soon as we are able to split (and resize)
+         ;; windows such that the new (or resized) windows can get a
+         ;; size less than the user-specified `window-min-height' and
+         ;; `window-min-width'.
+         (let ((frame (window-frame window))
+               (fringes (window-fringes window))
+               (scroll-bars (window-scroll-bars window)))
+           (max
+            (+ window-safe-min-width
+               (ceiling (car fringes) (frame-char-width frame))
+               (ceiling (cadr fringes) (frame-char-width frame))
+               (cond
+                ((memq (nth 2 scroll-bars) '(left right))
+                 (nth 1 scroll-bars))
+                ((memq (frame-parameter frame 'vertical-scroll-bars)
+                       '(left right))
+                 (ceiling (or (frame-parameter frame 'scroll-bar-width) 14)
+                          (frame-char-width)))
+                (t 0)))
+            (if (and (not (window-size-ignore window ignore))
+                     (numberp window-min-width))
+                window-min-width
+              0))))
+        (t
+         ;; For the minimum height of a window take any mode- or
+         ;; header-line into account.
+         (max (+ window-safe-min-height
+                 (if header-line-format 1 0)
+                 (if mode-line-format 1 0))
+              (if (and (not (window-size-ignore window ignore))
+                       (numberp window-min-height))
+                  window-min-height
+                0))))))))
+
+(defun window-sizable (window delta &optional horizontal ignore)
+  "Return DELTA if DELTA lines can be added to WINDOW.
+Optional argument HORIZONTAL non-nil means return DELTA if DELTA
+columns can be added to WINDOW.  A return value of zero means
+that no lines (or columns) can be added to WINDOW.
+
+This function looks only at WINDOW and its subwindows.  The
+function `window-resizable' looks at other windows as well.
+
+DELTA positive means WINDOW shall be enlarged by DELTA lines or
+columns.  If WINDOW cannot be enlarged by DELTA lines or columns
+return the maximum value in the range 0..DELTA by which WINDOW
+can be enlarged.
+
+DELTA negative means WINDOW shall be shrunk by -DELTA lines or
+columns.  If WINDOW cannot be shrunk by -DELTA lines or columns,
+return the minimum value in the range DELTA..0 by which WINDOW
+can be shrunk.
+
+Optional argument IGNORE non-nil means ignore any restrictions
+imposed by fixed size windows, `window-min-height' or
+`window-min-width' settings.  IGNORE equal `safe' means live
+windows may get as small as `window-safe-min-height' lines and
+`window-safe-min-width' columns.  IGNORE any window means ignore
+restrictions for that window only."
+  (setq window (normalize-any-window window))
+  (cond
+   ((< delta 0)
+    (max (- (window-min-size window horizontal ignore)
+           (window-total-size window horizontal))
+        delta))
+   ((window-size-ignore window ignore)
+    delta)
+   ((> delta 0)
+    (if (window-size-fixed-p window horizontal)
+       0
+      delta))
+   (t 0)))
+
+(defsubst window-sizable-p (window delta &optional horizontal ignore)
+  "Return t if WINDOW can be resized by DELTA lines.
+For the meaning of the arguments of this function see the
+doc-string of `window-sizable'."
+  (setq window (normalize-any-window window))
+  (if (> delta 0)
+      (>= (window-sizable window delta horizontal ignore) delta)
+    (<= (window-sizable window delta horizontal ignore) delta)))
+
+(defun window-size-fixed-1 (window horizontal)
+  "Internal function for `window-size-fixed-p'."
+  (let ((sub (window-child window)))
+    (catch 'fixed
+      (if sub
+         ;; WINDOW is an internal window.
+         (if (window-iso-combined-p sub horizontal)
+             ;; An iso-combination is fixed size if all its subwindows
+             ;; are fixed-size.
+             (progn
+               (while sub
+                 (unless (window-size-fixed-1 sub horizontal)
+                   ;; We found a non-fixed-size subwindow, so WINDOW's
+                   ;; size is not fixed.
+                   (throw 'fixed nil))
+                 (setq sub (window-right sub)))
+               ;; All subwindows are fixed-size, so WINDOW's size is
+               ;; fixed.
+               (throw 'fixed t))
+           ;; An ortho-combination is fixed-size if at least one of its
+           ;; subwindows is fixed-size.
+           (while sub
+             (when (window-size-fixed-1 sub horizontal)
+               ;; We found a fixed-size subwindow, so WINDOW's size is
+               ;; fixed.
+               (throw 'fixed t))
+             (setq sub (window-right sub))))
+       ;; WINDOW is a live window.
+       (with-current-buffer (window-buffer window)
+         (if horizontal
+             (memq window-size-fixed '(width t))
+           (memq window-size-fixed '(height t))))))))
+
+(defun window-size-fixed-p (&optional window horizontal)
+  "Return non-nil if WINDOW's height is fixed.
+WINDOW can be an arbitrary window and defaults to the selected
+window.  Optional argument HORIZONTAL non-nil means return
+non-nil if WINDOW's width is fixed.
+
+If this function returns nil, this does not necessarily mean that
+WINDOW can be resized in the desired direction.  The functions
+`window-resizable' and `window-resizable-p' will tell that."
+  (window-size-fixed-1
+   (normalize-any-window window) horizontal))
+
+(defun window-min-delta-1 (window delta &optional horizontal ignore trail noup)
+  "Internal function for `window-min-delta'."
+  (if (not (window-parent window))
+      ;; If we can't go up, return zero.
+      0
+    ;; Else try to find a non-fixed-size sibling of WINDOW.
+    (let* ((parent (window-parent window))
+          (sub (window-child parent)))
+      (catch 'done
+       (if (window-iso-combined-p sub horizontal)
+           ;; In an iso-combination throw DELTA if we find at least one
+           ;; subwindow and that subwindow is either not of fixed-size
+           ;; or we can ignore fixed-sizeness.
+           (let ((skip (eq trail 'after)))
+             (while sub
+               (cond
+                ((eq sub window)
+                 (setq skip (eq trail 'before)))
+                (skip)
+                ((and (not (window-size-ignore window ignore))
+                      (window-size-fixed-p sub horizontal)))
+                (t
+                 ;; We found a non-fixed-size subwindow.
+                 (throw 'done delta)))
+               (setq sub (window-right sub))))
+         ;; In an ortho-combination set DELTA to the minimum value by
+         ;; which other subwindows can shrink.
+         (while sub
+           (unless (eq sub window)
+             (setq delta
+                   (min delta
+                        (- (window-total-size sub horizontal)
+                           (window-min-size sub horizontal ignore)))))
+           (setq sub (window-right sub))))
+       (if noup
+           delta
+         (window-min-delta-1 parent delta horizontal ignore trail))))))
+
+(defun window-min-delta (&optional window horizontal ignore trail noup nodown)
+  "Return number of lines by which WINDOW can be shrunk.
+WINDOW can be an arbitrary window and defaults to the selected
+window.  Return zero if WINDOW cannot be shrunk.
+
+Optional argument HORIZONTAL non-nil means return number of
+columns by which WINDOW can be shrunk.
+
+Optional argument IGNORE non-nil means ignore any restrictions
+imposed by fixed size windows, `window-min-height' or
+`window-min-width' settings.  IGNORE a window means ignore
+restrictions for that window only.  IGNORE equal `safe' means
+live windows may get as small as `window-safe-min-height' lines
+and `window-safe-min-width' columns.
+
+Optional argument TRAIL `before' means only windows to the left
+of or above WINDOW can be enlarged.  Optional argument TRAIL
+`after' means only windows to the right of or below WINDOW can be
+enlarged.
+
+Optional argument NOUP non-nil means don't go up in the window
+tree but try to enlarge windows within WINDOW's combination only.
+
+Optional argument NODOWN non-nil means don't check whether WINDOW
+itself \(and its subwindows) can be shrunk; check only whether at
+least one other windows can be enlarged appropriately."
+  (setq window (normalize-any-window window))
+  (let ((size (window-total-size window horizontal))
+       (minimum (window-min-size window horizontal ignore)))
+    (cond
+     (nodown
+      ;; If NODOWN is t, try to recover the entire size of WINDOW.
+      (window-min-delta-1 window size horizontal ignore trail noup))
+     ((= size minimum)
+      ;; If NODOWN is nil and WINDOW's size is already at its minimum,
+      ;; there's nothing to recover.
+      0)
+     (t
+      ;; Otherwise, try to recover whatever WINDOW is larger than its
+      ;; minimum size.
+      (window-min-delta-1
+       window (- size minimum) horizontal ignore trail noup)))))
+
+(defun window-max-delta-1 (window delta &optional horizontal ignore trail noup)
+  "Internal function of `window-max-delta'."
+  (if (not (window-parent window))
+      ;; Can't go up.  Return DELTA.
+      delta
+    (let* ((parent (window-parent window))
+          (sub (window-child parent)))
+      (catch 'fixed
+       (if (window-iso-combined-p sub horizontal)
+           ;; For an iso-combination calculate how much we can get from
+           ;; other subwindows.
+           (let ((skip (eq trail 'after)))
+             (while sub
+               (cond
+                ((eq sub window)
+                 (setq skip (eq trail 'before)))
+                (skip)
+                (t
+                 (setq delta
+                       (+ delta
+                          (- (window-total-size sub horizontal)
+                             (window-min-size sub horizontal ignore))))))
+               (setq sub (window-right sub))))
+         ;; For an ortho-combination throw DELTA when at least one
+         ;; subwindow is fixed-size.
+         (while sub
+           (when (and (not (eq sub window))
+                      (not (window-size-ignore sub ignore))
+                      (window-size-fixed-p sub horizontal))
+             (throw 'fixed delta))
+           (setq sub (window-right sub))))
+       (if noup
+           ;; When NOUP is nil, DELTA is all we can get.
+           delta
+         ;; Else try with parent of WINDOW, passing the DELTA we
+         ;; recovered so far.
+         (window-max-delta-1 parent delta horizontal ignore trail))))))
+
+(defun window-max-delta (&optional window horizontal ignore trail noup nodown)
+  "Return maximum number of lines WINDOW by which WINDOW can be enlarged.
+WINDOW can be an arbitrary window and defaults to the selected
+window.  The return value is zero if WINDOW cannot be enlarged.
+
+Optional argument HORIZONTAL non-nil means return maximum number
+of columns by which WINDOW can be enlarged.
+
+Optional argument IGNORE non-nil means ignore any restrictions
+imposed by fixed size windows, `window-min-height' or
+`window-min-width' settings.  IGNORE a window means ignore
+restrictions for that window only.  IGNORE equal `safe' means
+live windows may get as small as `window-safe-min-height' lines
+and `window-safe-min-width' columns.
+
+Optional argument TRAIL `before' means only windows to the left
+of or below WINDOW can be shrunk.  Optional argument TRAIL
+`after' means only windows to the right of or above WINDOW can be
+shrunk.
+
+Optional argument NOUP non-nil means don't go up in the window
+tree but try to obtain the entire space from windows within
+WINDOW's combination.
+
+Optional argument NODOWN non-nil means do not check whether
+WINDOW itself \(and its subwindows) can be enlarged; check only
+whether other windows can be shrunk appropriately."
+  (setq window (normalize-any-window window))
+  (if (and (not (window-size-ignore window ignore))
+          (not nodown) (window-size-fixed-p window horizontal))
+      ;; With IGNORE and NOWDON nil return zero if WINDOW has fixed
+      ;; size.
+      0
+    ;; WINDOW has no fixed size.
+    (window-max-delta-1 window 0 horizontal ignore trail noup)))
+
+;; Make NOUP also inhibit the min-size check.
+(defun window-resizable (window delta &optional horizontal ignore trail noup 
nodown)
+  "Return DELTA if WINDOW can be resized vertically by DELTA lines.
+Optional argument HORIZONTAL non-nil means return DELTA if WINDOW
+can be resized horizontally by DELTA columns.  A return value of
+zero means that WINDOW is not resizable.
+
+DELTA positive means WINDOW shall be enlarged by DELTA lines or
+columns.  If WINDOW cannot be enlarged by DELTA lines or columns
+return the maximum value in the range 0..DELTA by which WINDOW
+can be enlarged.
+
+DELTA negative means WINDOW shall be shrunk by -DELTA lines or
+columns.  If WINDOW cannot be shrunk by -DELTA lines or columns,
+return the minimum value in the range DELTA..0 that can be used
+for shrinking WINDOW.
+
+Optional argument IGNORE non-nil means ignore any restrictions
+imposed by fixed size windows, `window-min-height' or
+`window-min-width' settings.  IGNORE a window means ignore
+restrictions for that window only.  IGNORE equal `safe' means
+live windows may get as small as `window-safe-min-height' lines
+and `window-safe-min-width' columns.
+
+Optional argument TRAIL `before' means only windows to the left
+of or below WINDOW can be shrunk.  Optional argument TRAIL
+`after' means only windows to the right of or above WINDOW can be
+shrunk.
+
+Optional argument NOUP non-nil means don't go up in the window
+tree but try to distribute the space among the other windows
+within WINDOW's combination.
+
+Optional argument NODOWN non-nil means don't check whether WINDOW
+and its subwindows can be resized."
+  (setq window (normalize-any-window window))
+  (cond
+   ((< delta 0)
+    (max (- (window-min-delta window horizontal ignore trail noup nodown))
+        delta))
+   ((> delta 0)
+    (min (window-max-delta window horizontal ignore trail noup nodown)
+        delta))
+   (t 0)))
+
+(defun window-resizable-p (window delta &optional horizontal ignore trail noup 
nodown)
+  "Return t if WINDOW can be resized vertically by DELTA lines.
+For the meaning of the arguments of this function see the
+doc-string of `window-resizable'."
+  (setq window (normalize-any-window window))
+  (if (> delta 0)
+      (>= (window-resizable window delta horizontal ignore trail noup nodown)
+         delta)
+    (<= (window-resizable window delta horizontal ignore trail noup nodown)
+       delta)))
+
+(defsubst window-total-height (&optional window)
+  "Return the total number of lines of WINDOW.
+WINDOW can be any window and defaults to the selected one.  The
+return value includes WINDOW's mode line and header line, if any.
+If WINDOW is internal the return value is the sum of the total
+number of lines of WINDOW's child windows if these are vertically
+combined and the height of WINDOW's first child otherwise.
+
+Note: This function does not take into account the value of
+`line-spacing' when calculating the number of lines in WINDOW."
+  (window-total-size window))
+
+;; See discussion in bug#4543.
+(defsubst window-full-height-p (&optional window)
+  "Return t if WINDOW is as high as the containing frame.
+More precisely, return t if and only if the total height of
+WINDOW equals the total height of the root window of WINDOW's
+frame.  WINDOW can be any window and defaults to the selected
+one."
+  (setq window (normalize-any-window window))
+  (= (window-total-size window)
+     (window-total-size (frame-root-window window))))
+
+(defsubst window-total-width (&optional window)
+  "Return the total number of columns of WINDOW.
+WINDOW can be any window and defaults to the selected one.  The
+return value includes any vertical dividers or scrollbars of
+WINDOW.  If WINDOW is internal, the return value is the sum of
+the total number of columns of WINDOW's child windows if these
+are horizontally combined and the width of WINDOW's first child
+otherwise."
+  (window-total-size window t))
+
+(defsubst window-full-width-p (&optional window)
+  "Return t if WINDOW is as wide as the containing frame.
+More precisely, return t if and only if the total width of WINDOW
+equals the total width of the root window of WINDOW's frame.
+WINDOW can be any window and defaults to the selected one."
+  (setq window (normalize-any-window window))
+  (= (window-total-size window t)
+     (window-total-size (frame-root-window window) t)))
+
+(defsubst window-body-height (&optional window)
+  "Return the number of lines of WINDOW's body.
+WINDOW must be a live window and defaults to the selected one.
+
+The return value does not include WINDOW's mode line and header
 line, if any.  If a line at the bottom of the window is only
-partially visible, that line is included in the return value.
-If you do not want to include a partially visible bottom line
-in the return value, use `window-text-height' instead."
-  (or window (setq window (selected-window)))
-  (if (window-minibuffer-p window)
-      (window-height window)
-    (with-current-buffer (window-buffer window)
-      (max 1 (- (window-height window)
-               (if mode-line-format 1 0)
-               (if header-line-format 1 0))))))
-
-;; See discussion in bug#4543.
-(defun window-full-height-p (&optional window)
-  "Return non-nil if WINDOW is not the result of a vertical split.
-WINDOW defaults to the selected window.  (This function is not
-appropriate for minibuffers.)"
-  (unless window
-    (setq window (selected-window)))
-  (= (window-height window)
-     (window-height (frame-root-window (window-frame window)))))
+partially visible, that line is included in the return value.  If
+you do not want to include a partially visible bottom line in the
+return value, use `window-text-height' instead."
+  (window-body-size window))
+
+(defsubst window-body-width (&optional window)
+  "Return the number of columns of WINDOW's body.
+WINDOW must be a live window and defaults to the selected one.
+
+The return value does not include any vertical dividers or scroll
+bars owned by WINDOW.  On a window-system the return value does
+not include the number of columns used for WINDOW's fringes or
+display margins either."
+  (window-body-size window t))
 
 (defun one-window-p (&optional nomini all-frames)
   "Return non-nil if the selected window is the only window.


reply via email to

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