summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
authorMartin Rudalics <rudalics@gmx.at>2013-12-13 18:06:30 +0100
committerMartin Rudalics <rudalics@gmx.at>2013-12-13 18:06:30 +0100
commit71e6691e5c9347f53fc984ccba83065c5e9fabaf (patch)
tree25c303c98309f4df2dbfd0e1eeef781ef98a3bda /lisp
parent5035fbc19e2f569674237c61e6ffdd4719e092d5 (diff)
downloademacs-71e6691e5c9347f53fc984ccba83065c5e9fabaf.tar.gz
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.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog10
-rw-r--r--lisp/windmove.el37
-rw-r--r--lisp/window.el106
3 files changed, 96 insertions, 57 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 7b0e00d0251..b48563761c4 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -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.
diff --git a/lisp/windmove.el b/lisp/windmove.el
index 638240347c1..ad191b3a24f 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -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.
diff --git a/lisp/window.el b/lisp/window.el
index 714979d8df1..ba21dbc7bcc 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -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)