emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master 47f730e3: Add code for "preserving" window sizes.


From: Martin Rudalics
Subject: [Emacs-diffs] master 47f730e3: Add code for "preserving" window sizes.
Date: Thu, 18 Dec 2014 17:31:43 +0000

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

    Add code for "preserving" window sizes.
    
    * frame.c (frame_windows_min_size): New argument IGNORE.
    (adjust_frame_size): When called from change_frame_size call
    frame_windows_min_size with IGNORE Qt so we can ignore size
    restrictions.
    
    * dired.el (dired-pop-to-buffer): Call fit-window-to-buffer with
    `preserve-size' t.
    (dired-mark-pop-up): Preserve size of window showing marked
    files.
    * electric.el (Electric-pop-up-window):
    * help.el (resize-temp-buffer-window): Call fit-window-to-buffer
    with `preserve-size' t.
    * minibuffer.el (minibuffer-completion-help): Use
    `resize-temp-buffer-window' instead of `fit-window-to-buffer'
    (Bug#19355).  Preserve size of completions window.
    * register.el (register-preview): Preserve size of register
    preview window.
    * tmm.el (tmm-add-prompt): Call fit-window-to-buffer
    with `preserve-size' t (Bug#1291).
    * window.el (with-displayed-buffer-window): Add calls to
    `window-preserve-size'.
    (window-min-pixel-size, window--preservable-size)
    (window-preserve-size, window-preserved-size)
    (window--preserve-size, window--min-size-ignore-p): New
    functions.
    (window-min-size, window-min-delta, window--resizable)
    (window--resize-this-window, split-window-below)
    (split-window-right): Amend doc-string.
    (adjust-window-trailing-edge): Handle preserving window
    sizes.  Signal user-error instead of an error when there's no
    window above or below.
    (window--min-size-1, window-sizable, window--size-fixed-1)
    (window-size-fixed-p, window--min-delta-1)
    (frame-windows-min-size, window--max-delta-1, window-resize)
    (window--resize-child-windows, window--resize-siblings)
    (enlarge-window, shrink-window, split-window): Handle preserving
    window sizes.
    (window--state-put-2): Handle horizontal scroll bars.
    (window--display-buffer): Call `preserve-size' if asked for.
    (display-buffer): Mention `preserve-size' alist member in
    doc-string.
    (fit-window-to-buffer): New argument PRESERVE-SIZE.
---
 etc/NEWS           |    4 +
 lisp/ChangeLog     |   41 +++++
 lisp/dired.el      |    5 +-
 lisp/electric.el   |    5 +-
 lisp/help.el       |    7 +-
 lisp/minibuffer.el |    5 +-
 lisp/register.el   |    3 +-
 lisp/tmm.el        |   11 +-
 lisp/window.el     |  509 +++++++++++++++++++++++++++++++---------------------
 src/ChangeLog      |    7 +
 src/frame.c        |   10 +-
 src/window.c       |    6 +-
 12 files changed, 393 insertions(+), 220 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 865ae07..3880fd1 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -575,6 +575,10 @@ fullwidth frames, the behavior may depend on the toolkit 
used.
    specific frame does not resize that frame in order to preserve the
    number of columns or lines it displays.
 
+** New function `window-preserve-size' allows to preserve the size of
+windows without "fixing" it.  It's supported by `fit-window-to-buffer',
+`temp-buffer-resize-mode' and `display-buffer'.
+
 ** Tearoff menus and detachable toolbars for Gtk+ has been removed.
 Those features have been deprecated in Gtk+ for a long time.
 
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 1659027..46c8718 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,44 @@
+2014-12-18  Martin Rudalics  <address@hidden>
+
+       Add code for "preserving" window sizes.
+       * dired.el (dired-pop-to-buffer): Call fit-window-to-buffer with
+       `preserve-size' t.
+       (dired-mark-pop-up): Preserve size of window showing marked
+       files.
+       * electric.el (Electric-pop-up-window):
+       * help.el (resize-temp-buffer-window): Call fit-window-to-buffer
+       with `preserve-size' t.
+       * minibuffer.el (minibuffer-completion-help): Use
+       `resize-temp-buffer-window' instead of `fit-window-to-buffer'
+       (Bug#19355).  Preserve size of completions window.
+       * register.el (register-preview): Preserve size of register
+       preview window.
+       * tmm.el (tmm-add-prompt): Call fit-window-to-buffer
+       with `preserve-size' t (Bug#1291).
+       * window.el (with-displayed-buffer-window): Add calls to
+       `window-preserve-size'.
+       (window-min-pixel-size, window--preservable-size)
+       (window-preserve-size, window-preserved-size)
+       (window--preserve-size, window--min-size-ignore-p): New
+       functions.
+       (window-min-size, window-min-delta, window--resizable)
+       (window--resize-this-window, split-window-below)
+       (split-window-right): Amend doc-string.
+       (window--min-size-1, window-sizable, window--size-fixed-1)
+       (window-size-fixed-p, window--min-delta-1)
+       (frame-windows-min-size, window--max-delta-1, window-resize)
+       (window--resize-child-windows, window--resize-siblings)
+       (enlarge-window, shrink-window, split-window): Handle preserving
+       window sizes.
+       (adjust-window-trailing-edge): Handle preserving window
+       sizes.  Signal user-error instead of an error when there's no
+       window above or below.
+       (window--state-put-2): Handle horizontal scroll bars.
+       (window--display-buffer): Call `preserve-size' if asked for.
+       (display-buffer): Mention `preserve-size' alist member in
+       doc-string.
+       (fit-window-to-buffer): New argument PRESERVE-SIZE.
+
 2014-12-18  Dmitry Gutov  <address@hidden>
 
        * emacs-lisp/package.el (package-activate): Do not re-activate or
diff --git a/lisp/dired.el b/lisp/dired.el
index 4cc252c..909ba22 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -3059,7 +3059,7 @@ or \"* [3 files]\"."
   (when dired-shrink-to-fit
     ;; Try to not delete window when we want to display less than
     ;; `window-min-height' lines.
-    (fit-window-to-buffer (get-buffer-window buf) nil 1)))
+    (fit-window-to-buffer (get-buffer-window buf) nil 1 nil nil t)))
 
 (defcustom dired-no-confirm nil
   "A list of symbols for commands Dired should not confirm, or t.
@@ -3106,7 +3106,8 @@ argument or confirmation)."
       (with-displayed-buffer-window
        buffer
        (cons 'display-buffer-below-selected
-            '((window-height . fit-window-to-buffer)))
+            '((window-height . fit-window-to-buffer)
+              (preserve-size . (nil . t))))
        #'(lambda (window _value)
           (with-selected-window window
             (unwind-protect
diff --git a/lisp/electric.el b/lisp/electric.el
index 4bf5963..fa9666d 100644
--- a/lisp/electric.el
+++ b/lisp/electric.el
@@ -164,7 +164,10 @@
       ;; Don't shrink the window, but expand it if necessary.
       (goto-char (point-min))
       (unless (= (point-max) (window-end win t))
-       (fit-window-to-buffer win max-height))
+       ;; This call is executed even if the window existed before, was
+       ;; reused, ... contradicting a claim in the comment before this
+       ;; function.
+       (fit-window-to-buffer win max-height nil nil nil t))
       win)))
 
 ;;; Electric keys.
diff --git a/lisp/help.el b/lisp/help.el
index 44716a5..07b9627 100644
--- a/lisp/help.el
+++ b/lisp/help.el
@@ -1133,7 +1133,10 @@ of a horizontal combination, restrain its new size by
 `fit-window-to-buffer-horizontally' can inhibit resizing.
 
 If WINDOW is the root window of its frame, resize the frame
-provided `fit-frame-to-buffer' is non-nil."
+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)
                    (with-selected-window window
@@ -1155,7 +1158,7 @@ provided `fit-frame-to-buffer' is non-nil."
              (and (eq quit-cadr 'frame)
                     fit-frame-to-buffer
                     (eq window (frame-root-window window))))
-       (fit-window-to-buffer window height nil width))))
+       (fit-window-to-buffer window height nil width nil t))))
 
 ;;; Help windows.
 (defcustom help-window-select nil
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index ee97174..e1e6b0e 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -1818,7 +1818,10 @@ variables.")
              ,(if (eq (selected-window) (minibuffer-window))
                   'display-buffer-at-bottom
                 'display-buffer-below-selected))
-            (window-height . fit-window-to-buffer))
+           ,(when temp-buffer-resize-mode
+              '(window-height . resize-temp-buffer-window))
+           ,(when temp-buffer-resize-mode
+              '(preserve-size . (nil . t))))
           nil
           ;; Remove the base-size tail because `sort' requires a properly
           ;; nil-terminated list.
diff --git a/lisp/register.el b/lisp/register.el
index 2414606..aacd5d0 100644
--- a/lisp/register.el
+++ b/lisp/register.el
@@ -135,7 +135,8 @@ Format of each entry is controlled by the variable 
`register-preview-function'."
     (with-current-buffer-window
      buffer
      (cons 'display-buffer-below-selected
-          '((window-height . fit-window-to-buffer)))
+          '((window-height . fit-window-to-buffer)
+            (preserve-size . (nil . t))))
      nil
      (with-current-buffer standard-output
        (setq cursor-in-non-selected-windows nil)
diff --git a/lisp/tmm.el b/lisp/tmm.el
index 0972975..8aedb78 100644
--- a/lisp/tmm.el
+++ b/lisp/tmm.el
@@ -371,7 +371,6 @@ Stores a list of all the shortcuts in the free variable 
`tmm-short-cuts'."
   (unless tmm-c-prompt
     (error "No active menu entries"))
   (setq tmm-old-mb-map (tmm-define-keys t))
-  ;; Get window and hide it for electric mode to get correct size
   (or tmm-completion-prompt
       (add-hook 'completion-setup-hook
                 'tmm-completion-delete-prompt 'append))
@@ -381,9 +380,15 @@ Stores a list of all the shortcuts in the free variable 
`tmm-short-cuts'."
   (with-current-buffer "*Completions*"
     (tmm-remove-inactive-mouse-face)
     (when tmm-completion-prompt
-      (let ((inhibit-read-only t))
+      (let ((inhibit-read-only t)
+           (window (get-buffer-window "*Completions*")))
        (goto-char (point-min))
-       (insert tmm-completion-prompt))))
+       (insert tmm-completion-prompt)
+       (when window
+         ;; Try to show everything just inserted and preserve height of
+         ;; *Completions* window.  This should fix a behavior described
+         ;; in Bug#1291.
+         (fit-window-to-buffer window nil nil nil nil t)))))
   (insert tmm-c-prompt))
 
 (defun tmm-shortcut ()
diff --git a/lisp/window.el b/lisp/window.el
index b1acd93..c95b0d6 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -249,6 +249,12 @@ displays the buffer specified by BUFFER-OR-NAME before 
running BODY."
           (ignore-errors
             (funcall (cdr (assq 'window-height (cdr ,vaction))) ,window)))
 
+        (when (consp (cdr (assq 'preserve-size (cdr ,vaction))))
+          (window-preserve-size
+           ,window t (cadr (assq 'preserve-size (cdr ,vaction))))
+         (window-preserve-size
+           ,window nil (cddr (assq 'preserve-size (cdr ,vaction)))))
+
         (if (functionp ,vquit-function)
             (funcall ,vquit-function ,window ,value)
           ,value)))))
@@ -435,6 +441,14 @@ minimum pixel width of WINDOW."
       (window-safe-min-pixel-width window)
     (window-safe-min-pixel-height window)))
 
+(defun window-min-pixel-size (&optional window horizontal)
+  "Return the minimum pixel height of WINDOW.
+Optional argument HORIZONTAL non-nil means return the minimum
+pixel width of WINDOW."
+  (if horizontal
+      (window-min-pixel-width window)
+    (window-min-pixel-height window)))
+
 (defun window-combined-p (&optional window horizontal)
   "Return non-nil if WINDOW has siblings in a given direction.
 WINDOW must be a valid window and defaults to the selected one.
@@ -1215,9 +1229,73 @@ unless it has no other choice (like when deleting a 
neighboring
 window).")
 (make-variable-buffer-local 'window-size-fixed)
 
-(defun window--size-ignore-p (window ignore)
-  "Return non-nil if IGNORE says to ignore size restrictions for WINDOW."
-  (if (window-valid-p ignore) (eq window ignore) ignore))
+(defun window--preservable-size (window &optional horizontal)
+  "Return height of WINDOW as `window-preserve-size' would preserve it.
+Optional argument HORIZONTAL non-nil means to return the width of
+WINDOW as `window-preserve-size' would preserve it."
+  (if horizontal
+      (window-body-width window t)
+    (+ (window-body-height window t)
+       (window-header-line-height window)
+       (window-mode-line-height window))))
+
+(defun window-preserve-size (&optional window horizontal preserve)
+  "Preserve height of window WINDOW.
+WINDOW must be a live window and defaults to the selected one.
+Optional argument HORIZONTAL non-nil means preserve the width of
+WINDOW.
+
+PRESERVE t means to preserve the current height/width of WINDOW's
+body in frame and window resizing operations whenever possible.
+The height/width of WINDOW will change only if Emacs has no other
+choice.  Resizing a window whose height/width is preserved never
+throws an error.
+
+PRESERVE nil means to stop preserving the height/width of WINDOW,
+lifting the respective restraint induced by a previous call of
+`window-preserve-size' for WINDOW.  Calling `enlarge-window',
+`shrink-window', `split-window' or `fit-window-to-buffer' with
+WINDOW as argument also removes the respective restraint.
+
+Other values of PRESERVE are reserved for future use."
+  (setq window (window-normalize-window window t))
+  (let* ((parameter (window-parameter window 'window-preserved-size))
+        (width (nth 1 parameter))
+        (height (nth 2 parameter)))
+    (if horizontal
+       (set-window-parameter
+        window 'window-preserved-size
+        (list
+         (window-buffer window)
+         (and preserve (window--preservable-size window t))
+         height))
+      (set-window-parameter
+       window 'window-preserved-size
+       (list
+       (window-buffer window)
+       width
+       (and preserve (window--preservable-size window)))))))
+
+(defun window-preserved-size (&optional window horizontal)
+  "Return preserved height of window WINDOW.
+WINDOW must be a live window and defaults to the selected one.
+Optional argument HORIZONTAL non-nil means to return preserved
+width of WINDOW."
+  (setq window (window-normalize-window window t))
+  (let* ((parameter (window-parameter window 'window-preserved-size))
+        (buffer (nth 0 parameter))
+        (width (nth 1 parameter))
+        (height (nth 2 parameter)))
+    (when (eq buffer (window-buffer window))
+      (if horizontal width height))))
+
+(defun window--preserve-size (window horizontal)
+  "Return non-nil when the height of WINDOW shall be preserved.
+Optional argument HORIZONTAL non-nil means to return non-nil when
+the width of WINDOW shall be preserved."
+  (let ((size (window-preserved-size window horizontal)))
+    (and (numberp size)
+        (= size (window--preservable-size window horizontal)))))
 
 (defun window-safe-min-size (&optional window horizontal pixelwise)
   "Return safe minimum size of WINDOW.
@@ -1244,19 +1322,20 @@ Optional argument HORIZONTAL non-nil means return the 
minimum
 number of columns of WINDOW; otherwise return the minimum number
 of WINDOW's lines.
 
-Optional argument IGNORE, if non-nil, means ignore restrictions
-imposed by fixed size windows, `window-min-height' or
-`window-min-width' settings.  If IGNORE equals `safe', live
-windows may get as small as `window-safe-min-height' lines and
-`window-safe-min-width' columns.  If IGNORE is a window, ignore
-restrictions for that window only.  Any other non-nil value
-means ignore all of the above restrictions for all windows.
-
-Optional argument PIXELWISE non-nil means return the minimum pixel-size
-of WINDOW."
+The optional argument IGNORE has the same meaning as for
+`window-resizable'.  Optional argument PIXELWISE non-nil means
+return the minimum pixel-size of WINDOW."
   (window--min-size-1
    (window-normalize-window window) horizontal ignore pixelwise))
 
+(defun window--min-size-ignore-p (window horizontal ignore)
+  "Return non-nil if IGNORE says to ignore height restrictions for WINDOW.
+HORIZONTAL non-nil means to return non-nil if IGNORE says to
+ignore width restrictions for WINDOW."
+  (if (window-valid-p ignore)
+      (eq window ignore)
+    (not (memq ignore '(nil preserved)))))
+
 (defun window--min-size-1 (window horizontal ignore pixelwise)
   "Internal function of `window-min-size'."
   (let ((sub (window-child window)))
@@ -1283,8 +1362,7 @@ of 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))
+        ((window-size-fixed-p window horizontal ignore)
          ;; The minimum size of a fixed size window is its size.
          (window-size window horizontal pixelwise))
         ((eq ignore 'safe)
@@ -1313,12 +1391,12 @@ of WINDOW."
                     pixel-width
                   ;; Round up to next integral of columns.
                   (* (ceiling pixel-width char-size) char-size))
-                (if (window--size-ignore-p window ignore)
+                (if (window--min-size-ignore-p window horizontal ignore)
                     0
                   (window-min-pixel-width window)))
              (max
               (ceiling pixel-width char-size)
-              (if (window--size-ignore-p window ignore)
+              (if (window--min-size-ignore-p window horizontal ignore)
                   0
                 window-min-width)))))
         ((let ((char-size (frame-char-size window))
@@ -1334,11 +1412,11 @@ of WINDOW."
                     pixel-height
                   ;; Round up to next integral of lines.
                   (* (ceiling pixel-height char-size) char-size))
-                (if (window--size-ignore-p window ignore)
+                (if (window--min-size-ignore-p window horizontal ignore)
                     0
                   (window-min-pixel-height window)))
              (max (ceiling pixel-height char-size)
-                  (if (window--size-ignore-p window ignore)
+                  (if (window--min-size-ignore-p window horizontal ignore)
                       0
                     window-min-height))))))))))
 
@@ -1363,26 +1441,17 @@ 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 restrictions
-imposed by fixed size windows, `window-min-height' or
-`window-min-width' settings.  If IGNORE equals `safe', live
-windows may get as small as `window-safe-min-height' lines and
-`window-safe-min-width' columns.  If IGNORE is a window, ignore
-restrictions for that window only.  Any other non-nil value means
-ignore all of the above restrictions for all windows.
-
-Optional argument PIXELWISE non-nil means interpret DELTA as
-pixels."
+The optional argument IGNORE has the same meaning as for
+`window-resizable'.  Optional argument PIXELWISE non-nil means
+interpret DELTA as pixels."
   (setq window (window-normalize-window window))
   (cond
    ((< delta 0)
     (max (- (window-min-size window horizontal ignore pixelwise)
            (window-size window horizontal pixelwise))
         delta))
-   ((window--size-ignore-p window ignore)
-    delta)
    ((> delta 0)
-    (if (window-size-fixed-p window horizontal)
+    (if (window-size-fixed-p window horizontal ignore)
        0
       delta))
    (t 0)))
@@ -1399,7 +1468,7 @@ doc-string of `window-sizable'."
     (<= (window-sizable window delta horizontal ignore pixelwise)
        delta)))
 
-(defun window--size-fixed-1 (window horizontal)
+(defun window--size-fixed-1 (window horizontal ignore)
   "Internal function for `window-size-fixed-p'."
   (let ((sub (window-child window)))
     (catch 'fixed
@@ -1410,7 +1479,7 @@ doc-string of `window-sizable'."
              ;; windows are fixed-size.
              (progn
                (while sub
-                 (unless (window--size-fixed-1 sub horizontal)
+                 (unless (window--size-fixed-1 sub horizontal ignore)
                    ;; We found a non-fixed-size child window, so
                    ;; WINDOW's size is not fixed.
                    (throw 'fixed nil))
@@ -1421,28 +1490,33 @@ doc-string of `window-sizable'."
            ;; An ortho-combination is fixed-size if at least one of its
            ;; child windows is fixed-size.
            (while sub
-             (when (window--size-fixed-1 sub horizontal)
+             (when (window--size-fixed-1 sub horizontal ignore)
                ;; We found a fixed-size child window, 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)
+       (and (or (not (windowp ignore)) (not (eq window ignore)))
+            (or (and (not (eq ignore 'preserved))
+                     (window--preserve-size window horizontal))
+                (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 ignore)
   "Return non-nil if WINDOW's height is fixed.
 WINDOW must be a valid window and defaults to the selected one.
 Optional argument HORIZONTAL non-nil means return non-nil if
-WINDOW's width is fixed.
+WINDOW's width is fixed.  The optional argument IGNORE has the
+same meaning as for `window-resizable'.
 
 If this function returns nil, this does not necessarily mean that
 WINDOW can be resized in the desired direction.  The function
 `window-resizable' can tell that."
-  (window--size-fixed-1
-   (window-normalize-window window) horizontal))
+  (when (or (windowp ignore) (memq ignore '(nil preserved)))
+    (window--size-fixed-1
+     (window-normalize-window window) horizontal ignore)))
 
 (defun window--min-delta-1 (window delta &optional horizontal ignore trail 
noup pixelwise)
   "Internal function for `window-min-delta'."
@@ -1463,8 +1537,7 @@ WINDOW can be resized in the desired direction.  The 
function
                 ((eq sub window)
                  (setq skip (eq trail 'before)))
                 (skip)
-                ((and (not (window--size-ignore-p window ignore))
-                      (window-size-fixed-p sub horizontal)))
+                ((window-size-fixed-p sub horizontal ignore))
                 (t
                  ;; We found a non-fixed-size child window.
                  (throw 'done delta)))
@@ -1493,25 +1566,18 @@ 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 restrictions
-imposed by fixed size windows, `window-min-height' or
-`window-min-width' settings.  If IGNORE is a window, ignore
-restrictions for that window only.  If IGNORE equals `safe',
-live windows may get as small as `window-safe-min-height' lines
-and `window-safe-min-width' columns.  Any other non-nil value
-means ignore all of the above restrictions for all windows.
-
-Optional argument TRAIL restricts the windows that can be enlarged.
-If its value is `before', only windows to the left of or above WINDOW
-can be enlarged.  If it is `after', only windows to the right of or
-below WINDOW can be enlarged.
+The optional argument IGNORE has the same meaning as for
+`window-resizable'.  Optional argument TRAIL restricts the
+windows that can be enlarged.  If its value is `before', only
+windows to the left of or above WINDOW can be enlarged.  If it is
+`after', 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 child windows) can be shrunk; check only whether
-at least one other window can be enlarged appropriately.
+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 child windows) can be shrunk; check only
+whether at least one other window can be enlarged appropriately.
 
 Optional argument PIXELWISE non-nil means return number of pixels
 by which WINDOW can be shrunk."
@@ -1533,14 +1599,16 @@ 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)
+(defun frame-windows-min-size (&optional frame horizontal ignore 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."
+windows.  The optional argument IGNORE has the same meaning as
+for `window-resizable'.  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)
+    (+ (window-min-size root horizontal ignore pixelwise)
        (if (and mini (not horizontal))
           (window-min-size mini horizontal nil pixelwise)
         0))))
@@ -1575,8 +1643,7 @@ windows.  PIXELWISE non-nil means return sizes in pixels."
          ;; child window is fixed-size.
          (while sub
            (when (and (not (eq sub window))
-                      (not (window--size-ignore-p sub ignore))
-                      (window-size-fixed-p sub horizontal))
+                      (window-size-fixed-p sub horizontal ignore))
              (throw 'fixed delta))
            (setq sub (window-right sub))))
        (if noup
@@ -1595,32 +1662,24 @@ 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 restrictions
-imposed by fixed size windows, `window-min-height' or
-`window-min-width' settings.  If IGNORE is a window, ignore
-restrictions for that window only.  If IGNORE equals `safe',
-live windows may get as small as `window-safe-min-height' lines
-and `window-safe-min-width' columns.  Any other non-nil value means
-ignore all of the above restrictions for all windows.
-
-Optional argument TRAIL restricts the windows that can be enlarged.
-If its value is `before', only windows to the left of or above WINDOW
-can be enlarged.  If it is `after', only windows to the right of or
-below WINDOW can be enlarged.
+The optional argument IGNORE has the same meaning as for
+`window-resizable'.  Optional argument TRAIL restricts the
+windows that can be enlarged.  If its value is `before', only
+windows to the left of or above WINDOW can be enlarged.  If it is
+`after', 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 obtain the entire space from windows within
-WINDOW's combination.
-
-Optional argument NODOWN non-nil means do not check whether
-WINDOW itself (and its child windows) can be enlarged; check
-only whether other windows can be shrunk appropriately.
+WINDOW's combination.  Optional argument NODOWN non-nil means do
+not check whether WINDOW itself (and its child windows) can be
+enlarged; check only whether other windows can be shrunk
+appropriately.
 
 Optional argument PIXELWISE non-nil means return number of
 pixels by which WINDOW can be enlarged."
   (setq window (window-normalize-window window))
-  (if (and (not (window--size-ignore-p window ignore))
-          (not nodown) (window-size-fixed-p window horizontal))
+  (if (and (not nodown) (window-size-fixed-p window horizontal ignore))
       ;; With IGNORE and NOWDON nil return zero if WINDOW has fixed
       ;; size.
       0
@@ -1645,26 +1704,18 @@ 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 restrictions
-imposed by fixed size windows, `window-min-height' or
-`window-min-width' settings.  If IGNORE is a window, ignore
-restrictions for that window only.  If IGNORE equals `safe',
-live windows may get as small as `window-safe-min-height' lines
-and `window-safe-min-width' columns.  Any other non-nil value
-means ignore all of the above restrictions for all windows.
-
-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.
+The optional argument IGNORE has the same meaning as for
+`window-resizable'.  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 check only whether space can be obtained from (or given
-to) WINDOW's siblings.
-
-Optional argument NODOWN non-nil means don't go down in the
-window tree.  This means do not check whether resizing would
-violate size restrictions of WINDOW or its child windows.
+to) WINDOW's siblings.  Optional argument NODOWN non-nil means
+don't go down in the window tree.  This means do not check
+whether resizing would violate size restrictions of WINDOW or its
+child windows.
 
 Optional argument PIXELWISE non-nil means interpret DELTA as
 number of pixels."
@@ -1714,13 +1765,14 @@ 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 restrictions
-imposed by fixed size windows, `window-min-height' or
-`window-min-width' settings.  If IGNORE is a window, ignore
-restrictions for that window only.  If IGNORE equals `safe',
-live windows may get as small as `window-safe-min-height' lines
-and `window-safe-min-width' columns.  Any other non-nil value
-means ignore all of the above restrictions for all windows.
+Optional argument IGNORE, if non-nil, means to ignore restraints
+induced by fixed size windows or the values of the variables
+`window-min-height' and `window-min-width'.  The following values
+have special meanings: `safe' means that in addition live windows
+are allowed to get as small as `window-safe-min-height' lines and
+`window-safe-min-width' columns.  `preserved' means to ignore
+only restrictions induced by `window-preserve-size'.  If IGNORE
+is a window, then ignore restrictions for that window only.
 
 Optional argument PIXELWISE non-nil means interpret DELTA as
 pixels."
@@ -2419,13 +2471,14 @@ horizontally by DELTA columns.  In this case a positive 
DELTA
 means enlarge WINDOW by DELTA columns.  DELTA negative means
 WINDOW shall be shrunk by -DELTA columns.
 
-Optional argument IGNORE non-nil means ignore restrictions
-imposed by fixed size windows, `window-min-height' or
-`window-min-width' settings.  If IGNORE is a window, ignore
-restrictions for that window only.  If IGNORE equals `safe',
-live windows may get as small as `window-safe-min-height' lines
-and `window-safe-min-width' columns.  Any other non-nil value
-means ignore all of the above restrictions for all windows.
+Optional argument IGNORE, if non-nil, means to ignore restraints
+induced by fixed size windows or the values of the variables
+`window-min-height' and `window-min-width'.  The following values
+have special meanings: `safe' means that in addition live windows
+are allowed to get as small as `window-safe-min-height' lines and
+`window-safe-min-width' columns.  `preserved' means to ignore
+only restrictions induced by `window-preserve-size'.  If IGNORE
+is a window, then ignore restrictions for that window only.
 
 Optional argument PIXELWISE non-nil means resize WINDOW by DELTA
 pixels.
@@ -2456,8 +2509,12 @@ instead."
       ;; nil or the minibuffer window is active, resize the minibuffer
       ;; window.
       (window--resize-mini-window minibuffer-window (- delta)))
-     ((window--resizable-p
-       window delta horizontal ignore nil nil nil t)
+     ((or (window--resizable-p
+          window delta horizontal ignore nil nil nil t)
+         (and (not ignore)
+              (setq ignore 'preserved)
+              (window--resizable-p
+               window delta horizontal ignore nil nil nil t)))
       (window--resize-reset frame horizontal)
       (window--resize-this-window window delta horizontal ignore t)
       (if (and (not window-combination-resize)
@@ -2615,13 +2672,8 @@ be a horizontally combined internal window.
 WINDOW, if specified, must denote a child window of PARENT that
 is resized by DELTA pixels.
 
-Optional argument IGNORE non-nil means ignore restrictions
-imposed by fixed size windows, `window-min-height' or
-`window-min-width' settings.  If IGNORE equals `safe', live
-windows may get as small as `window-safe-min-height' lines and
-`window-safe-min-width' columns.  If IGNORE is a window, ignore
-restrictions for that window only.  Any other non-nil value means
-ignore all of the above restrictions for all windows.
+The optional argument IGNORE has the same meaning as for
+`window-resizable'.
 
 Optional arguments TRAIL and EDGE, when non-nil, restrict the set
 of windows that shall be resized.  If TRAIL equals `before',
@@ -2692,7 +2744,7 @@ already set by this routine."
              ;; Ignore windows to skip and fixed-size child windows -
              ;; in the latter case make it a window to skip.
              (and (not ignore)
-                  (window-size-fixed-p sub horizontal)
+                  (window-size-fixed-p sub horizontal ignore)
                   (set-window-new-normal sub 'ignore))))
         ((< delta 0)
          ;; When shrinking store the number of lines/cols we can get
@@ -2798,13 +2850,8 @@ Optional argument HORIZONTAL non-nil means resize other 
windows
 when WINDOW is resized horizontally by DELTA pixels.  WINDOW
 itself is not resized by this function.
 
-Optional argument IGNORE non-nil means ignore restrictions
-imposed by fixed size windows, `window-min-height' or
-`window-min-width' settings.  If IGNORE equals `safe', live
-windows may get as small as `window-safe-min-height' lines and
-`window-safe-min-width' columns.  If IGNORE is a window, ignore
-restrictions for that window only.  Any other non-nil value means
-ignore all of the above restrictions for all windows.
+The optional argument IGNORE has the same meaning as for
+`window-resizable'.
 
 Optional arguments TRAIL and EDGE, when non-nil, refine the set
 of windows that shall be resized.  If TRAIL equals `before',
@@ -2831,8 +2878,7 @@ preferably only resize windows adjacent to EDGE."
                ;; Make sure this sibling is left alone when
                ;; resizing its siblings.
                (set-window-new-normal sub 'ignore))
-              ((or (window--size-ignore-p sub ignore)
-                   (not (window-size-fixed-p sub horizontal)))
+              ((not (window-size-fixed-p sub horizontal ignore))
                ;; Set this-delta to t to signal that we found a sibling
                ;; of WINDOW whose size is not fixed.
                (setq this-delta t)))
@@ -2902,16 +2948,9 @@ preferably only resize windows adjacent to EDGE."
 Optional argument HORIZONTAL non-nil means resize WINDOW
 horizontally by DELTA pixels.
 
-Optional argument IGNORE non-nil means ignore restrictions
-imposed by fixed size windows, `window-min-height' or
-`window-min-width' settings.  If IGNORE equals `safe', live
-windows may get as small as `window-safe-min-height' lines and
-`window-safe-min-width' columns.  If IGNORE is a window, ignore
-restrictions for that window only.  Any other non-nil value
-means ignore all of the above restrictions for all windows.
-
-Optional argument ADD non-nil means add DELTA to the new total
-size of WINDOW.
+The optional argument IGNORE has the same meaning as for
+`window-resizable'.  Optional argument ADD non-nil means add
+DELTA to the new total size of WINDOW.
 
 Optional arguments TRAIL and EDGE, when non-nil, refine the set
 of windows that shall be resized.  If TRAIL equals `before',
@@ -3057,7 +3096,7 @@ move it as far as possible in the desired direction."
   (let* ((frame (window-frame window))
         (minibuffer-window (minibuffer-window frame))
         (right window)
-        left this-delta min-delta max-delta)
+        left this-delta min-delta max-delta ignore)
 
     (unless pixelwise
       (setq pixelwise t)
@@ -3080,12 +3119,16 @@ move it as far as possible in the desired direction."
       (window--resize-mini-window minibuffer-window (- delta)))
      ((or (not (setq left right)) (not (setq right (window-right right))))
       (if horizontal
-         (error "No window on the right of this one")
-       (error "No window below this one")))
+         (user-error "No window on the right of this one")
+       (user-error "No window below this one")))
      (t
       ;; Set LEFT to the first resizable window on the left.  This step is
       ;; needed to handle fixed-size windows.
-      (while (and left (window-size-fixed-p left horizontal))
+      (while (and left
+                 (or (window-size-fixed-p left horizontal)
+                     (and (< delta 0)
+                          (<= (window-size left horizontal t)
+                              (window-min-size left horizontal nil t)))))
        (setq left
              (or (window-left left)
                  (progn
@@ -3093,13 +3136,31 @@ move it as far as possible in the desired direction."
                                (not (window-combined-p left horizontal))))
                    (window-left left)))))
       (unless left
-       (if horizontal
-           (error "No resizable window on the left of this one")
-         (error "No resizable window above this one")))
+       (setq ignore 'preserved)
+       (setq left window)
+       (while (and left
+                   (or (window-size-fixed-p left horizontal 'preserved)
+                       (<= (window-size left horizontal t)
+                           (window-min-size left horizontal 'preserved t))))
+         (setq left
+               (or (window-left left)
+                   (progn
+                     (while (and (setq left (window-parent left))
+                                 (not (window-combined-p left horizontal))))
+                     (window-left left)))))
+
+       (unless left
+         (if horizontal
+             (user-error "No resizable window on the left of this one")
+           (user-error "No resizable window above this one"))))
 
       ;; Set RIGHT to the first resizable window on the right.  This step
       ;; is needed to handle fixed-size windows.
-      (while (and right (window-size-fixed-p right horizontal))
+      (while (and right
+                 (or (window-size-fixed-p right horizontal)
+                     (and (> delta 0)
+                          (<= (window-size right horizontal t)
+                              (window-min-size right horizontal 'preserved 
t)))))
        (setq right
              (or (window-right right)
                  (progn
@@ -3107,9 +3168,22 @@ move it as far as possible in the desired direction."
                                (not (window-combined-p right horizontal))))
                    (window-right right)))))
       (unless right
-       (if horizontal
-           (error "No resizable window on the right of this one")
-         (error "No resizable window below this one")))
+       (setq ignore 'preserved)
+       (setq right (window-right window))
+       (while (and right
+                   (or (window-size-fixed-p right horizontal 'preserved))
+                   (<= (window-size right horizontal t)
+                       (window-min-size right horizontal nil t)))
+         (setq right
+               (or (window-right right)
+                   (progn
+                     (while (and (setq right (window-parent right))
+                                 (not (window-combined-p right horizontal))))
+                     (window-right right)))))
+       (unless right
+         (if horizontal
+             (user-error "No resizable window on the right of this one")
+           (user-error "No resizable window below this one"))))
 
       ;; LEFT and RIGHT (which might be both internal windows) are now the
       ;; two windows we want to resize.
@@ -3117,10 +3191,10 @@ move it as far as possible in the desired direction."
        ((> delta 0)
        (setq max-delta
              (window--max-delta-1
-              left 0 horizontal nil 'after nil pixelwise))
+              left 0 horizontal ignore 'after nil pixelwise))
        (setq min-delta
              (window--min-delta-1
-              right (- delta) horizontal nil 'before nil pixelwise))
+              right (- delta) horizontal ignore 'before nil pixelwise))
        (when (or (< max-delta delta) (> min-delta (- delta)))
          ;; We can't get the whole DELTA - move as far as possible.
          (setq delta (min max-delta (- min-delta))))
@@ -3129,26 +3203,26 @@ move it as far as possible in the desired direction."
          (window--resize-reset frame horizontal)
          ;; Try to enlarge LEFT first.
          (setq this-delta (window--resizable
-                           left delta horizontal nil 'after nil nil pixelwise))
+                           left delta horizontal ignore 'after nil nil 
pixelwise))
          (unless (zerop this-delta)
            (window--resize-this-window
-            left this-delta horizontal nil t 'before
+            left this-delta horizontal ignore t 'before
             (if horizontal
                 (+ (window-pixel-left left) (window-pixel-width left))
               (+ (window-pixel-top left) (window-pixel-height left)))))
          ;; Shrink windows on right of LEFT.
          (window--resize-siblings
-          left delta horizontal nil 'after
+          left delta horizontal ignore 'after
           (if horizontal
               (window-pixel-left right)
             (window-pixel-top right)))))
        ((< delta 0)
        (setq max-delta
              (window--max-delta-1
-              right 0 horizontal nil 'before nil pixelwise))
+              right 0 horizontal ignore 'before nil pixelwise))
        (setq min-delta
              (window--min-delta-1
-              left delta horizontal nil 'after nil pixelwise))
+              left delta horizontal ignore 'after nil pixelwise))
        (when (or (< max-delta (- delta)) (> min-delta delta))
          ;; We can't get the whole DELTA - move as far as possible.
          (setq delta (max (- max-delta) min-delta)))
@@ -3158,16 +3232,16 @@ move it as far as possible in the desired direction."
          ;; Try to enlarge RIGHT.
          (setq this-delta
                (window--resizable
-                right (- delta) horizontal nil 'before nil nil pixelwise))
+                right (- delta) horizontal ignore 'before nil nil pixelwise))
          (unless (zerop this-delta)
            (window--resize-this-window
-            right this-delta horizontal nil t 'after
+            right this-delta horizontal ignore t 'after
             (if horizontal
                 (window-pixel-left right)
               (window-pixel-top right))))
          ;; Shrink windows on left of RIGHT.
          (window--resize-siblings
-          right (- delta) horizontal nil 'before
+          right (- delta) horizontal ignore 'before
           (if horizontal
               (+ (window-pixel-left left) (window-pixel-width left))
             (+ (window-pixel-top left) (window-pixel-height left)))))))
@@ -3189,6 +3263,8 @@ make selected window wider by DELTA columns.  If DELTA is
 negative, shrink selected window by -DELTA lines or columns."
   (interactive "p")
   (let ((minibuffer-window (minibuffer-window)))
+    (when (window-preserved-size nil horizontal)
+      (window-preserve-size nil horizontal))
     (cond
      ((zerop delta))
      ((window-size-fixed-p nil horizontal)
@@ -3222,6 +3298,8 @@ negative, enlarge selected window by -DELTA lines or 
columns.
 Also see the `window-min-height' variable."
   (interactive "p")
   (let ((minibuffer-window (minibuffer-window)))
+    (when (window-preserved-size nil horizontal)
+      (window-preserve-size nil horizontal))
     (cond
      ((zerop delta))
      ((window-size-fixed-p nil horizontal)
@@ -4363,7 +4441,7 @@ frame.  The selected window is not changed by this 
function."
         (divider-width (if horizontal
                            (frame-right-divider-width frame)
                          (frame-bottom-divider-width frame)))
-        atom-root)
+        atom-root ignore)
     (window--check frame)
     (catch 'done
       (cond
@@ -4427,10 +4505,11 @@ frame.  The selected window is not changed by this 
function."
                (if resize
                    ;; When resizing try to give the new window the
                    ;; average size of a window in its combination.
-                   (min (- parent-pixel-size
-                           (window-min-size parent horizontal nil t))
-                        (/ parent-pixel-size
-                           (1+ (window-combinations parent horizontal))))
+                   (max (min (- parent-pixel-size
+                                (window-min-size parent horizontal nil t))
+                             (/ parent-pixel-size
+                                (1+ (window-combinations parent horizontal))))
+                        (window-min-pixel-size))
                  ;; Else try to give the new window half the size
                  ;; of WINDOW (plus an eventual odd pixel).
                  (/ old-pixel-size 2)))
@@ -4459,12 +4538,20 @@ frame.  The selected window is not changed by this 
function."
          (cond
           (resize
            ;; SIZE unspecified, resizing.
-           (unless (window-sizable-p
-                    parent (- new-pixel-size divider-width) horizontal nil t)
+           (unless (or (window-sizable-p
+                        parent (- (+ new-pixel-size divider-width)) horizontal
+                        nil t)
+                       (window-sizable-p
+                        parent (- (+ new-pixel-size divider-width)) horizontal
+                        (setq ignore 'preserved) 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)
+          ((and (> (+ new-pixel-size divider-width
+                      (window-min-size window horizontal nil t))
+                   old-pixel-size)
+                (> (+ new-pixel-size divider-width
+                      (window-min-size
+                       window horizontal (setq ignore 'preserved) t))
+                   old-pixel-size))
            ;; SIZE unspecified, no resizing.
            (error "Window %s too small for splitting (2)" window))))
         ((and (>= pixel-size 0)
@@ -4477,8 +4564,12 @@ frame.  The selected window is not changed by this 
function."
          (error "Window %s too small for splitting (3)" window))
         (resize
          ;; SIZE specified, resizing.
-         (unless (window-sizable-p
-                  parent (- new-pixel-size divider-width) horizontal nil t)
+         (unless (or (window-sizable-p
+                      parent (- (+ new-pixel-size divider-width)) horizontal
+                      nil t)
+                     (window-sizable-p
+                      parent (- (+ new-pixel-size divider-width)) horizontal
+                      (setq ignore 'preserved) t))
            ;; If we cannot resize the parent give up.
            (error "Window %s too small for splitting (4)" parent)))
         ((or (< new-pixel-size
@@ -4512,7 +4603,7 @@ frame.  The selected window is not changed by this 
function."
            ;; delete the one we create here.  Hence we do not go up.
            (progn
              (window--resize-child-windows
-              parent (- new-pixel-size) horizontal)
+              parent (- new-pixel-size) horizontal nil ignore)
              (let* ((normal (- 1.0 new-normal))
                     (sub (window-child parent)))
                (while sub
@@ -4522,10 +4613,8 @@ frame.  The selected window is not changed by this 
function."
          ;; Get entire space from WINDOW.
          (set-window-new-pixel
           window (- old-pixel-size new-pixel-size))
-;;       (set-window-new-pixel window (- old-pixel-size new-pixel-size))
-;;       (set-window-new-total
-;;        window (- old-size new-size))
-         (window--resize-this-window window (- new-pixel-size) horizontal)
+         (window--resize-this-window
+          window (- new-pixel-size) horizontal ignore)
          (set-window-new-normal
           window (- (if new-parent 1.0 (window-normal-size window horizontal))
                     new-normal)))
@@ -4579,7 +4668,7 @@ the original point in both windows."
 (defun split-window-below (&optional size)
   "Split the selected window into two windows, one above the other.
 The selected window is above.  The newly split-off window is
-below, and displays the same buffer.  Return the new window.
+below and displays the same buffer.  Return the new window.
 
 If optional argument SIZE is omitted or nil, both windows get the
 same height, or close to it.  If SIZE is positive, the upper
@@ -4633,7 +4722,7 @@ amount of redisplay; this is convenient on slow 
terminals."
 (defun split-window-right (&optional size)
   "Split the selected window into two side-by-side windows.
 The selected window is on the left.  The newly split-off window
-is on the right, and displays the same buffer.  Return the new
+is on the right and displays the same buffer.  Return the new
 window.
 
 If optional argument SIZE is omitted or nil, both windows get the
@@ -5131,7 +5220,7 @@ value can be also stored on disk and read back in a new 
session."
                (let ((scroll-bars (cdr (assq 'scroll-bars state))))
                  (set-window-scroll-bars
                   window (car scroll-bars) (nth 2 scroll-bars)
-                  (or (nth 3 scroll-bars) 0) (nth 5 scroll-bars)))
+                  (nth 3 scroll-bars) (nth 5 scroll-bars)))
                (set-window-vscroll window (cdr (assq 'vscroll state)))
                ;; Adjust vertically.
                (if (memq window-size-fixed '(t height))
@@ -5967,7 +6056,8 @@ live."
     (let ((parameter (window-parameter window 'quit-restore))
          (height (cdr (assq 'window-height alist)))
          (width (cdr (assq 'window-width alist)))
-         (size (cdr (assq 'window-size alist))))
+         (size (cdr (assq 'window-size alist)))
+         (preserve-size (cdr (assq 'preserve-size alist))))
       (cond
        ((or (eq type 'frame)
            (and (eq (car parameter) 'same)
@@ -6022,7 +6112,11 @@ live."
                       (window-combined-p window t))
              (window-resize window delta t 'safe))))
         ((functionp width)
-         (ignore-errors (funcall width window)))))))
+         (ignore-errors (funcall width window))))
+       ;; Preserve window size if asked for.
+       (when (consp preserve-size)
+         (window-preserve-size window t (car preserve-size))
+         (window-preserve-size window nil (cdr preserve-size))))))
 
     window))
 
@@ -6241,6 +6335,10 @@ Recognized alist entries include:
     of not displaying the buffer and FUNCTION can safely return
     a non-window value to suppress displaying.
 
+ `preserve-size' -- Value should be either '(t . nil)' to
+    preserve the width of the window, '(nil . t)' to preserve its
+    height or '(t . t)' to preserve both.
+
 The ACTION argument to `display-buffer' can also have a non-nil
 and non-list value.  This means to display the buffer in a window
 other than the selected one, even if it is already displayed in
@@ -7242,7 +7340,7 @@ FRAME."
           (frame-text-height))
         frame-resize-pixelwise)))))
 
-(defun fit-window-to-buffer (&optional window max-height min-height max-width 
min-width)
+(defun fit-window-to-buffer (&optional window max-height min-height max-width 
min-width preserve-size)
   "Adjust size of WINDOW to display its buffer's contents exactly.
 WINDOW must be a live window and defaults to the selected one.
 
@@ -7266,6 +7364,9 @@ and defaults to `window-min-width'.  Both MAX-WIDTH and 
MIN-WIDTH
 are specified in columns and include fringes, margins, a
 scrollbar and a vertical divider, if any.
 
+If the optional argument `preserve-size' is non-nil, preserve the
+size of WINDOW (see `window-preserve-size').
+
 Fit pixelwise if the option `window-resize-pixelwise' is non-nil.
 If WINDOW is its frame's root window and the option
 `fit-frame-to-buffer' is non-nil, call `fit-frame-to-buffer' to
@@ -7307,25 +7408,25 @@ accessible position."
                (max (if pixelwise
                         (* char-height window-min-height)
                       window-min-height)
-                    (window-min-size nil nil t pixelwise))))
+                    (window-min-size window nil window pixelwise))))
             (max-height
              ;; Sanitize MAX-HEIGHT.
              (if (numberp max-height)
                  (min
                   (+ total-height
                      (window-max-delta
-                      window nil nil nil nil nil pixelwise))
+                      window nil window nil nil nil pixelwise))
                   (if pixelwise
                       (* char-height max-height)
                     max-height))
                (+ total-height (window-max-delta
-                                window nil nil nil nil nil pixelwise))))
+                                window nil window nil nil 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))
+              (not (window-size-fixed-p window 'preserved))
               (window-combined-p))
          ;; Vertically we always want to fit the entire buffer.
          ;; WINDOW'S height can't get larger than its frame's pixel
@@ -7338,14 +7439,17 @@ accessible position."
          (unless pixelwise
            (setq height (/ (+ height char-height -1) char-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)))
+            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))
+              (not (window-size-fixed-p window t 'preserved))
               (window-combined-p nil t))
          (let* ((total-width (window-size window t pixelwise))
                 (min-width
@@ -7362,18 +7466,18 @@ accessible position."
                    (max (if pixelwise
                             (* char-width window-min-width)
                           window-min-width)
-                        (window-min-size nil nil t pixelwise))))
+                        (window-min-size nil nil window pixelwise))))
                 (max-width
                  ;; Sanitize MAX-WIDTH.
                  (if (numberp max-width)
                      (min (+ total-width
                              (window-max-delta
-                              nil t nil nil nil nil pixelwise))
+                              window t window nil nil nil pixelwise))
                           (if pixelwise
                               (* char-width max-width)
                             max-width))
                    (+ total-width (window-max-delta
-                                   nil t nil nil nil nil pixelwise))))
+                                   window t window nil nil 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
@@ -7391,13 +7495,16 @@ accessible position."
            (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)))))))))
+              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.
diff --git a/src/ChangeLog b/src/ChangeLog
index 2b125d5..6fabfb4 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,10 @@
+2014-12-18  Martin Rudalics  <address@hidden>
+
+       * frame.c (frame_windows_min_size): New argument IGNORE.
+       (adjust_frame_size): When called from change_frame_size call
+       frame_windows_min_size with IGNORE Qt so we can ignore size
+       restrictions.
+
 2014-12-18  Eli Zaretskii  <address@hidden>
 
        * font.c (Ffont_info): Add more font information to the vector
diff --git a/src/frame.c b/src/frame.c
index eaab63a..3127366 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -335,9 +335,9 @@ predicates which report frame's specific UI-related 
capabilities.  */)
 }
 
 static int
-frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal, Lisp_Object 
pixelwise)
+frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal, Lisp_Object 
ignore, Lisp_Object pixelwise)
 {
-  return XINT (call3 (Qframe_windows_min_size, frame, horizontal, pixelwise));
+  return XINT (call4 (Qframe_windows_min_size, frame, horizontal, ignore, 
pixelwise));
 }
 
 
@@ -419,8 +419,10 @@ adjust_frame_size (struct frame *f, int new_width, int 
new_height, int inhibit,
   /* The following two values are calculated from the old window body
      sizes and any "new" settings for scroll bars, dividers, fringes and
      margins (though the latter should have been processed already).  */
-  min_windows_width = frame_windows_min_size (frame, Qt, Qt);
-  min_windows_height = frame_windows_min_size (frame, Qnil, Qt);
+  min_windows_width
+    = frame_windows_min_size (frame, Qt, (inhibit == 5) ? Qt : Qnil, Qt);
+  min_windows_height
+    = frame_windows_min_size (frame, Qnil, (inhibit == 5) ? Qt : Qnil, Qt);
 
   if (inhibit >= 2 && inhibit <= 4)
     /* If INHIBIT is in [2..4] inhibit if the "old" window sizes stay
diff --git a/src/window.c b/src/window.c
index ca2bc74..2177a1d 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4135,11 +4135,7 @@ values.  */)
 
 /* Resize frame F's windows when number of lines of F is set to SIZE.
    HORFLAG 1 means resize windows when number of columns of F is set to
-   SIZE.  PIXELWISE 1 means to interpret SIZE as pixels.
-
-   This function can delete all windows but the selected one in order to
-   satisfy the request.  The result will be meaningful if and only if
-   F's windows have meaningful sizes when you call this.  */
+   SIZE.  PIXELWISE 1 means to interpret SIZE as pixels.  */
 void
 resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
 {



reply via email to

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