]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix windmove-find-other-window broken after pixelwise resizing (Bug#16017).
authorMartin Rudalics <rudalics@gmx.at>
Fri, 13 Dec 2013 17:06:30 +0000 (18:06 +0100)
committerMartin Rudalics <rudalics@gmx.at>
Fri, 13 Dec 2013 17:06:30 +0000 (18:06 +0100)
* windmove.el (windmove-other-window-loc): Revert change from
2013-12-04.
(windmove-find-other-window): Call window-in-direction.
* window.el (window-in-direction): New arguments SIGN, WRAP and
MINI to emulate original windmove-find-other-window behavior.

lisp/ChangeLog
lisp/windmove.el
lisp/window.el

index 7b0e00d02514b21925eb1bcbd450df34192e4306..b48563761c47a770c7bbb36b007f05b816c90fcc 100644 (file)
@@ -1,3 +1,13 @@
+2013-12-13  Martin Rudalics  <rudalics@gmx.at>
+
+       Fix windmove-find-other-window broken after pixelwise resizing
+       (Bug#16017).
+       * windmove.el (windmove-other-window-loc): Revert change from
+       2013-12-04.
+       (windmove-find-other-window): Call window-in-direction.
+       * window.el (window-in-direction): New arguments SIGN, WRAP and
+       MINI to emulate original windmove-find-other-window behavior.
+
 2013-12-13  Dmitry Gutov  <dgutov@yandex.ru>
 
        * simple.el (blink-matching--overlay): New variable.
index 638240347c15890a9812ead98c940ae6d4620d4b..ad191b3a24f0cefc24778c1a1f60e51023bae582 100644 (file)
@@ -438,49 +438,38 @@ Return value is a frame-based (HPOS . VPOS) value that should be moved
 to.  DIR is one of `left', `up', `right', or `down'; an optional ARG
 is handled as by `windmove-reference-loc'; WINDOW is the window that
 movement is relative to."
-  (let ((edges (window-pixel-edges window))   ; edges: (x0, y0, x1, y1)
+  (let ((edges (window-edges window))   ; edges: (x0, y0, x1, y1)
         (refpoint (windmove-reference-loc arg window))) ; (x . y)
     (cond
      ((eq dir 'left)
-      (cons (- (ceiling (nth 0 edges)
-                       (frame-char-width (window-frame window)))
+      (cons (- (nth 0 edges)
                windmove-window-distance-delta)
             (cdr refpoint)))            ; (x0-d, y)
      ((eq dir 'up)
       (cons (car refpoint)
-            (- (ceiling (nth 1 edges)
-                       (frame-char-height (window-frame window)))
+            (- (nth 1 edges)
                windmove-window-distance-delta))) ; (x, y0-d)
      ((eq dir 'right)
-      (cons (+ (1- (ceiling (nth 2 edges)
-                           (frame-char-width (window-frame window))))  ; -1 to get actual max x
+      (cons (+ (1- (nth 2 edges))      ; -1 to get actual max x
                windmove-window-distance-delta)
             (cdr refpoint)))            ; (x1+d-1, y)
      ((eq dir 'down)                   ; -1 to get actual max y
       (cons (car refpoint)
-            (+ (1- (ceiling (nth 3 edges)
-                           (frame-char-height (window-frame window))))
+            (+ (1- (nth 3 edges))
                windmove-window-distance-delta))) ; (x, y1+d-1)
      (t (error "Invalid direction of movement: %s" dir)))))
 
+;; Rewritten on 2013-12-13 using `window-in-direction'.  After the
+;; pixelwise change the old approach didn't work any more.  martin
 (defun windmove-find-other-window (dir &optional arg window)
   "Return the window object in direction DIR.
 DIR, ARG, and WINDOW are handled as by `windmove-other-window-loc'."
-  (let* ((actual-current-window (or window (selected-window)))
-         (raw-other-window-loc
-          (windmove-other-window-loc dir arg actual-current-window))
-         (constrained-other-window-loc
-          (windmove-constrain-loc-for-movement raw-other-window-loc
-                                               actual-current-window
-                                               dir))
-         (other-window-loc
-          (if windmove-wrap-around
-            (windmove-wrap-loc-for-movement constrained-other-window-loc
-                                            actual-current-window)
-            constrained-other-window-loc)))
-    (window-at (car other-window-loc)
-               (cdr other-window-loc))))
-
+  (window-in-direction
+   (cond
+    ((eq dir 'up) 'above)
+    ((eq dir 'down) 'below)
+    (t dir))
+   window nil arg windmove-wrap-around t))
 
 ;; Selects the window that's hopefully at the location returned by
 ;; `windmove-other-window-loc', or screams if there's no window there.
index 714979d8df124272788a5ae423fd3ab8abab818e..ba21dbc7bcc65a0be8bf25b99c12290b67c708bc 100644 (file)
@@ -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)