Fix recent w32_enable_frame_resize_hack and display-buffer-below-selected fixes.
[bpt/emacs.git] / lisp / window.el
index 7978623..c6238ff 100644 (file)
@@ -807,13 +807,13 @@ SIDE.  Return the new window, nil if its creation window failed."
     (delete-window window)))
 
 (defun display-buffer-in-side-window (buffer alist)
-  "Display BUFFER in a window on side SIDE of the selected frame.
+  "Display BUFFER in a side window of the selected frame.
 ALIST is an association list of symbols and values.  The
-following symbols can be used:
+following special symbols can be used in ALIST.
 
-`side' denotes the side of the existing window where the new
-  window shall be located.  Valid values are `bottom', `right',
-  `top' and `left'.  The default is `bottom'.
+`side' denotes the side of the frame where the new window shall
+  be located.  Valid values are `bottom', `right', `top' and
+  `left'.  The default is `bottom'.
 
 `slot' if non-nil, specifies the window slot where to display
   BUFFER.  A value of zero or nil means use the middle slot on
@@ -1719,7 +1719,7 @@ SIDE can be any of the symbols `left', `top', `right' or
 ;; Neither of these allow to selectively ignore specific windows
 ;; (windows whose `no-other-window' parameter is non-nil) as targets of
 ;; the movement.
-(defun window-in-direction (direction &optional window ignore)
+(defun window-in-direction (direction &optional window ignore sign wrap mini)
   "Return window in DIRECTION as seen from WINDOW.
 More precisely, return the nearest window in direction DIRECTION
 as seen from the position of `window-point' in window WINDOW.
@@ -1732,6 +1732,22 @@ non-nil, try to find another window in the indicated direction.
 If, however, the optional argument IGNORE is non-nil, return that
 window even if its `no-other-window' parameter is non-nil.
 
+Optional argument SIGN a negative number means to use the right
+or bottom edge of WINDOW as reference position instead of
+`window-point'.  SIGN a positive number means to use the left or
+top edge of WINDOW as reference position.
+
+Optional argument WRAP non-nil means to wrap DIRECTION around
+frame borders.  This means to return for a WINDOW a the top of
+the frame and DIRECTION `above' to return the minibuffer window
+if the frame has one, and a window at the bottom of the frame
+otherwise.
+
+Optional argument MINI nil means to return the minibuffer window
+if and only if it is currently active.  MINI non-nil means to
+return the minibuffer window even when it's not active.  However,
+if WRAP non-nil, always act as if MINI were nil.
+
 Return nil if no suitable window can be found."
   (setq window (window-normalize-window window t))
   (unless (memq direction '(above below left right))
@@ -1742,12 +1758,22 @@ Return nil if no suitable window can be found."
                    (window-pixel-left window)
                  (window-pixel-top window)))
         (last (+ first (window-size window hor t)))
-        (posn-cons (nth 2 (posn-at-point (window-point window) window)))
         ;; The column / row value of `posn-at-point' can be nil for the
         ;; mini-window, guard against that.
-        (posn (if hor
-                  (+ (or (cdr posn-cons) 1) (window-pixel-top window))
-                (+ (or (car posn-cons) 1) (window-pixel-left window))))
+        (posn
+         (cond
+          ((and (numberp sign) (< sign 0))
+           (if hor
+               (1- (+ (window-pixel-top window) (window-pixel-height window)))
+             (1- (+ (window-pixel-left window) (window-pixel-width window)))))
+          ((and (numberp sign) (> sign 0))
+           (if hor
+               (window-pixel-top window)
+             (window-pixel-left window)))
+          ((let ((posn-cons (nth 2 (posn-at-point (window-point window) window))))
+             (if hor
+                 (+ (or (cdr posn-cons) 1) (window-pixel-top window))
+               (+ (or (car posn-cons) 1) (window-pixel-left window)))))))
         (best-edge
          (cond
           ((eq direction 'below) (frame-pixel-height frame))
@@ -1772,9 +1798,15 @@ Return nil if no suitable window can be found."
                  (< posn (+ w-top (window-pixel-height w))))
             ;; W is to the left or right of WINDOW and covers POSN.
             (when (or (and (eq direction 'left)
-                           (<= w-left first) (> w-left best-edge))
+                           (or (and (<= w-left first) (> w-left best-edge))
+                               (and wrap
+                                    (window-at-side-p window 'left)
+                                    (window-at-side-p w 'right))))
                       (and (eq direction 'right)
-                           (>= w-left last) (< w-left best-edge)))
+                           (or (and (>= w-left last) (< w-left best-edge))
+                               (and wrap
+                                    (window-at-side-p window 'right)
+                                    (window-at-side-p w 'left)))))
               (setq best-edge w-left)
               (setq best w)))
            ((and (or (and (eq direction 'left)
@@ -1792,32 +1824,40 @@ Return nil if no suitable window can be found."
             (setq best-edge-2 w-left)
             (setq best-diff-2 best-diff-2-new)
             (setq best-2 w))))
-         (t
-          (cond
-           ((and (<= w-left posn)
-                 (< posn (+ w-left (window-pixel-width w))))
-            ;; W is above or below WINDOW and covers POSN.
-            (when (or (and (eq direction 'above)
-                           (<= w-top first) (> w-top best-edge))
-                      (and (eq direction 'below)
-                           (>= w-top first) (< w-top best-edge)))
-              (setq best-edge w-top)
-              (setq best w)))
-           ((and (or (and (eq direction 'above)
-                          (<= (+ w-top (window-pixel-height w)) first))
-                     (and (eq direction 'below) (<= last w-top)))
-                 ;; W is above or below WINDOW but does not cover POSN.
-                 (setq best-diff-2-new
-                       (window--in-direction-2 w posn hor))
-                 (or (< best-diff-2-new best-diff-2)
-                     (and (= best-diff-2-new best-diff-2)
-                          (if (eq direction 'above)
-                              (> w-top best-edge-2)
-                            (< w-top best-edge-2)))))
-            (setq best-edge-2 w-top)
-            (setq best-diff-2 best-diff-2-new)
-            (setq best-2 w)))))))
-     frame)
+         ((and (<= w-left posn)
+               (< posn (+ w-left (window-pixel-width w))))
+          ;; W is above or below WINDOW and covers POSN.
+          (when (or (and (eq direction 'above)
+                         (or (and (<= w-top first) (> w-top best-edge))
+                             (and wrap
+                                  (window-at-side-p window 'top)
+                                  (if (active-minibuffer-window)
+                                      (minibuffer-window-active-p w)
+                                    (window-at-side-p w 'bottom)))))
+                    (and (eq direction 'below)
+                         (or (and (>= w-top first) (< w-top best-edge))
+                             (and wrap
+                                  (if (active-minibuffer-window)
+                                      (minibuffer-window-active-p window)
+                                    (window-at-side-p window 'bottom))
+                                  (window-at-side-p w 'top)))))
+            (setq best-edge w-top)
+            (setq best w)))
+         ((and (or (and (eq direction 'above)
+                        (<= (+ w-top (window-pixel-height w)) first))
+                   (and (eq direction 'below) (<= last w-top)))
+               ;; W is above or below WINDOW but does not cover POSN.
+               (setq best-diff-2-new
+                     (window--in-direction-2 w posn hor))
+               (or (< best-diff-2-new best-diff-2)
+                   (and (= best-diff-2-new best-diff-2)
+                        (if (eq direction 'above)
+                            (> w-top best-edge-2)
+                          (< w-top best-edge-2)))))
+          (setq best-edge-2 w-top)
+          (setq best-diff-2 best-diff-2-new)
+          (setq best-2 w)))))
+     frame nil (and mini t))
     (or best best-2)))
 
 (defun get-window-with-predicate (predicate &optional minibuf all-frames default)
@@ -5851,13 +5891,8 @@ This is a list of elements (CONDITION . ACTION), where:
 
 `display-buffer' scans this alist until it either finds a
 matching regular expression or the function specified by a
-condition returns non-nil.  It can pass (no-display-ok . t) in
-its action alist to indicate readiness for the case of not
-displaying the buffer and FUNCTION can safely return a non-window
-value to suppress displaying.
-
-In any of these cases, it adds the associated action to the list
-of actions it will try."
+condition returns non-nil.  In any of these cases, it adds the
+associated action to the list of actions it will try."
   :type `(alist :key-type
                (choice :tag "Condition"
                        regexp
@@ -5939,8 +5974,9 @@ ALIST is an arbitrary association list (alist).
 Each such FUNCTION should accept two arguments: the buffer to
 display and an alist.  Based on those arguments, it should
 display the buffer and return the window.  If the caller is
-prepared to handle the case of not displaying the buffer it
-should pass (no-display-ok . t) as an element of the ALIST.
+prepared to handle the case of not displaying the buffer
+and returning nil from `display-buffer' it should pass
+\(allow-no-window . t) as an element of the ALIST.
 
 The `display-buffer' function builds a function list and an alist
 by combining the functions and alists specified in
@@ -5995,6 +6031,10 @@ Recognized alist entries include:
     argument - a new window.  The function is supposed to adjust
     the width of the window; its return value is ignored.
 
+ `allow-no-window' -- A non-nil value indicates readiness for the case
+    of not displaying the buffer and FUNCTION can safely return
+    a non-window value to suppress displaying.
+
 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
@@ -6205,7 +6245,9 @@ This either splits the selected window or reuses the window below
 the selected one."
   (let (window)
     (or (and (not (frame-parameter nil 'unsplittable))
-            (setq window (window--try-to-split-window (selected-window) alist))
+            (let ((split-height-threshold 0)
+                  split-width-threshold)
+              (setq window (window--try-to-split-window (selected-window) alist)))
             (window--display-buffer
              buffer window 'window alist display-buffer-mark-dedicated))
        (and (setq window (window-in-direction 'below))
@@ -6337,6 +6379,16 @@ that frame."
        (unless (cdr (assq 'inhibit-switch-frame alist))
          (window--maybe-raise-frame (window-frame window)))))))
 
+(defun display-buffer-no-window (buffer alist)
+  "Display BUFFER in no window.
+If ALIST has a non-nil `allow-no-window' entry, then don't display
+a window at all.  This makes possible to override the default action
+and avoid displaying the buffer.  It is assumed that when the caller
+specifies a non-nil `allow-no-window' then it can handle a nil value
+returned from `display-buffer' in this case."
+  (when (cdr (assq 'allow-no-window alist))
+    'fail))
+
 ;;; Display + selection commands:
 (defun pop-to-buffer (buffer &optional action norecord)
   "Select buffer BUFFER in some window, preferably a different one.