aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Rudalics2013-12-13 18:06:30 +0100
committerMartin Rudalics2013-12-13 18:06:30 +0100
commit71e6691e5c9347f53fc984ccba83065c5e9fabaf (patch)
tree25c303c98309f4df2dbfd0e1eeef781ef98a3bda
parent5035fbc19e2f569674237c61e6ffdd4719e092d5 (diff)
downloademacs-71e6691e5c9347f53fc984ccba83065c5e9fabaf.tar.gz
emacs-71e6691e5c9347f53fc984ccba83065c5e9fabaf.zip
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.
-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 @@
12013-12-13 Martin Rudalics <rudalics@gmx.at>
2
3 Fix windmove-find-other-window broken after pixelwise resizing
4 (Bug#16017).
5 * windmove.el (windmove-other-window-loc): Revert change from
6 2013-12-04.
7 (windmove-find-other-window): Call window-in-direction.
8 * window.el (window-in-direction): New arguments SIGN, WRAP and
9 MINI to emulate original windmove-find-other-window behavior.
10
12013-12-13 Dmitry Gutov <dgutov@yandex.ru> 112013-12-13 Dmitry Gutov <dgutov@yandex.ru>
2 12
3 * simple.el (blink-matching--overlay): New variable. 13 * 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
438to. DIR is one of `left', `up', `right', or `down'; an optional ARG 438to. DIR is one of `left', `up', `right', or `down'; an optional ARG
439is handled as by `windmove-reference-loc'; WINDOW is the window that 439is handled as by `windmove-reference-loc'; WINDOW is the window that
440movement is relative to." 440movement is relative to."
441 (let ((edges (window-pixel-edges window)) ; edges: (x0, y0, x1, y1) 441 (let ((edges (window-edges window)) ; edges: (x0, y0, x1, y1)
442 (refpoint (windmove-reference-loc arg window))) ; (x . y) 442 (refpoint (windmove-reference-loc arg window))) ; (x . y)
443 (cond 443 (cond
444 ((eq dir 'left) 444 ((eq dir 'left)
445 (cons (- (ceiling (nth 0 edges) 445 (cons (- (nth 0 edges)
446 (frame-char-width (window-frame window)))
447 windmove-window-distance-delta) 446 windmove-window-distance-delta)
448 (cdr refpoint))) ; (x0-d, y) 447 (cdr refpoint))) ; (x0-d, y)
449 ((eq dir 'up) 448 ((eq dir 'up)
450 (cons (car refpoint) 449 (cons (car refpoint)
451 (- (ceiling (nth 1 edges) 450 (- (nth 1 edges)
452 (frame-char-height (window-frame window)))
453 windmove-window-distance-delta))) ; (x, y0-d) 451 windmove-window-distance-delta))) ; (x, y0-d)
454 ((eq dir 'right) 452 ((eq dir 'right)
455 (cons (+ (1- (ceiling (nth 2 edges) 453 (cons (+ (1- (nth 2 edges)) ; -1 to get actual max x
456 (frame-char-width (window-frame window)))) ; -1 to get actual max x
457 windmove-window-distance-delta) 454 windmove-window-distance-delta)
458 (cdr refpoint))) ; (x1+d-1, y) 455 (cdr refpoint))) ; (x1+d-1, y)
459 ((eq dir 'down) ; -1 to get actual max y 456 ((eq dir 'down) ; -1 to get actual max y
460 (cons (car refpoint) 457 (cons (car refpoint)
461 (+ (1- (ceiling (nth 3 edges) 458 (+ (1- (nth 3 edges))
462 (frame-char-height (window-frame window))))
463 windmove-window-distance-delta))) ; (x, y1+d-1) 459 windmove-window-distance-delta))) ; (x, y1+d-1)
464 (t (error "Invalid direction of movement: %s" dir))))) 460 (t (error "Invalid direction of movement: %s" dir)))))
465 461
462;; Rewritten on 2013-12-13 using `window-in-direction'. After the
463;; pixelwise change the old approach didn't work any more. martin
466(defun windmove-find-other-window (dir &optional arg window) 464(defun windmove-find-other-window (dir &optional arg window)
467 "Return the window object in direction DIR. 465 "Return the window object in direction DIR.
468DIR, ARG, and WINDOW are handled as by `windmove-other-window-loc'." 466DIR, ARG, and WINDOW are handled as by `windmove-other-window-loc'."
469 (let* ((actual-current-window (or window (selected-window))) 467 (window-in-direction
470 (raw-other-window-loc 468 (cond
471 (windmove-other-window-loc dir arg actual-current-window)) 469 ((eq dir 'up) 'above)
472 (constrained-other-window-loc 470 ((eq dir 'down) 'below)
473 (windmove-constrain-loc-for-movement raw-other-window-loc 471 (t dir))
474 actual-current-window 472 window nil arg windmove-wrap-around t))
475 dir))
476 (other-window-loc
477 (if windmove-wrap-around
478 (windmove-wrap-loc-for-movement constrained-other-window-loc
479 actual-current-window)
480 constrained-other-window-loc)))
481 (window-at (car other-window-loc)
482 (cdr other-window-loc))))
483
484 473
485;; Selects the window that's hopefully at the location returned by 474;; Selects the window that's hopefully at the location returned by
486;; `windmove-other-window-loc', or screams if there's no window there. 475;; `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
1719;; Neither of these allow to selectively ignore specific windows 1719;; Neither of these allow to selectively ignore specific windows
1720;; (windows whose `no-other-window' parameter is non-nil) as targets of 1720;; (windows whose `no-other-window' parameter is non-nil) as targets of
1721;; the movement. 1721;; the movement.
1722(defun window-in-direction (direction &optional window ignore) 1722(defun window-in-direction (direction &optional window ignore sign wrap mini)
1723 "Return window in DIRECTION as seen from WINDOW. 1723 "Return window in DIRECTION as seen from WINDOW.
1724More precisely, return the nearest window in direction DIRECTION 1724More precisely, return the nearest window in direction DIRECTION
1725as seen from the position of `window-point' in window WINDOW. 1725as 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.
1732If, however, the optional argument IGNORE is non-nil, return that 1732If, however, the optional argument IGNORE is non-nil, return that
1733window even if its `no-other-window' parameter is non-nil. 1733window even if its `no-other-window' parameter is non-nil.
1734 1734
1735Optional argument SIGN a negative number means to use the right
1736or bottom edge of WINDOW as reference position instead of
1737`window-point'. SIGN a positive number means to use the left or
1738top edge of WINDOW as reference position.
1739
1740Optional argument WRAP non-nil means to wrap DIRECTION around
1741frame borders. This means to return for a WINDOW a the top of
1742the frame and DIRECTION `above' to return the minibuffer window
1743if the frame has one, and a window at the bottom of the frame
1744otherwise.
1745
1746Optional argument MINI nil means to return the minibuffer window
1747if and only if it is currently active. MINI non-nil means to
1748return the minibuffer window even when it's not active. However,
1749if WRAP non-nil, always act as if MINI were nil.
1750
1735Return nil if no suitable window can be found." 1751Return nil if no suitable window can be found."
1736 (setq window (window-normalize-window window t)) 1752 (setq window (window-normalize-window window t))
1737 (unless (memq direction '(above below left right)) 1753 (unless (memq direction '(above below left right))
@@ -1742,12 +1758,22 @@ Return nil if no suitable window can be found."
1742 (window-pixel-left window) 1758 (window-pixel-left window)
1743 (window-pixel-top window))) 1759 (window-pixel-top window)))
1744 (last (+ first (window-size window hor t))) 1760 (last (+ first (window-size window hor t)))
1745 (posn-cons (nth 2 (posn-at-point (window-point window) window)))
1746 ;; The column / row value of `posn-at-point' can be nil for the 1761 ;; The column / row value of `posn-at-point' can be nil for the
1747 ;; mini-window, guard against that. 1762 ;; mini-window, guard against that.
1748 (posn (if hor 1763 (posn
1749 (+ (or (cdr posn-cons) 1) (window-pixel-top window)) 1764 (cond
1750 (+ (or (car posn-cons) 1) (window-pixel-left window)))) 1765 ((and (numberp sign) (< sign 0))
1766 (if hor
1767 (1- (+ (window-pixel-top window) (window-pixel-height window)))
1768 (1- (+ (window-pixel-left window) (window-pixel-width window)))))
1769 ((and (numberp sign) (> sign 0))
1770 (if hor
1771 (window-pixel-top window)
1772 (window-pixel-left window)))
1773 ((let ((posn-cons (nth 2 (posn-at-point (window-point window) window))))
1774 (if hor
1775 (+ (or (cdr posn-cons) 1) (window-pixel-top window))
1776 (+ (or (car posn-cons) 1) (window-pixel-left window)))))))
1751 (best-edge 1777 (best-edge
1752 (cond 1778 (cond
1753 ((eq direction 'below) (frame-pixel-height frame)) 1779 ((eq direction 'below) (frame-pixel-height frame))
@@ -1772,9 +1798,15 @@ Return nil if no suitable window can be found."
1772 (< posn (+ w-top (window-pixel-height w)))) 1798 (< posn (+ w-top (window-pixel-height w))))
1773 ;; W is to the left or right of WINDOW and covers POSN. 1799 ;; W is to the left or right of WINDOW and covers POSN.
1774 (when (or (and (eq direction 'left) 1800 (when (or (and (eq direction 'left)
1775 (<= w-left first) (> w-left best-edge)) 1801 (or (and (<= w-left first) (> w-left best-edge))
1802 (and wrap
1803 (window-at-side-p window 'left)
1804 (window-at-side-p w 'right))))
1776 (and (eq direction 'right) 1805 (and (eq direction 'right)
1777 (>= w-left last) (< w-left best-edge))) 1806 (or (and (>= w-left last) (< w-left best-edge))
1807 (and wrap
1808 (window-at-side-p window 'right)
1809 (window-at-side-p w 'left)))))
1778 (setq best-edge w-left) 1810 (setq best-edge w-left)
1779 (setq best w))) 1811 (setq best w)))
1780 ((and (or (and (eq direction 'left) 1812 ((and (or (and (eq direction 'left)
@@ -1792,32 +1824,40 @@ Return nil if no suitable window can be found."
1792 (setq best-edge-2 w-left) 1824 (setq best-edge-2 w-left)
1793 (setq best-diff-2 best-diff-2-new) 1825 (setq best-diff-2 best-diff-2-new)
1794 (setq best-2 w)))) 1826 (setq best-2 w))))
1795 (t 1827 ((and (<= w-left posn)
1796 (cond 1828 (< posn (+ w-left (window-pixel-width w))))
1797 ((and (<= w-left posn) 1829 ;; W is above or below WINDOW and covers POSN.
1798 (< posn (+ w-left (window-pixel-width w)))) 1830 (when (or (and (eq direction 'above)
1799 ;; W is above or below WINDOW and covers POSN. 1831 (or (and (<= w-top first) (> w-top best-edge))
1800 (when (or (and (eq direction 'above) 1832 (and wrap
1801 (<= w-top first) (> w-top best-edge)) 1833 (window-at-side-p window 'top)
1802 (and (eq direction 'below) 1834 (if (active-minibuffer-window)
1803 (>= w-top first) (< w-top best-edge))) 1835 (minibuffer-window-active-p w)
1804 (setq best-edge w-top) 1836 (window-at-side-p w 'bottom)))))
1805 (setq best w))) 1837 (and (eq direction 'below)
1806 ((and (or (and (eq direction 'above) 1838 (or (and (>= w-top first) (< w-top best-edge))
1807 (<= (+ w-top (window-pixel-height w)) first)) 1839 (and wrap
1808 (and (eq direction 'below) (<= last w-top))) 1840 (if (active-minibuffer-window)
1809 ;; W is above or below WINDOW but does not cover POSN. 1841 (minibuffer-window-active-p window)
1810 (setq best-diff-2-new 1842 (window-at-side-p window 'bottom))
1811 (window--in-direction-2 w posn hor)) 1843 (window-at-side-p w 'top)))))
1812 (or (< best-diff-2-new best-diff-2) 1844 (setq best-edge w-top)
1813 (and (= best-diff-2-new best-diff-2) 1845 (setq best w)))
1814 (if (eq direction 'above) 1846 ((and (or (and (eq direction 'above)
1815 (> w-top best-edge-2) 1847 (<= (+ w-top (window-pixel-height w)) first))
1816 (< w-top best-edge-2))))) 1848 (and (eq direction 'below) (<= last w-top)))
1817 (setq best-edge-2 w-top) 1849 ;; W is above or below WINDOW but does not cover POSN.
1818 (setq best-diff-2 best-diff-2-new) 1850 (setq best-diff-2-new
1819 (setq best-2 w))))))) 1851 (window--in-direction-2 w posn hor))
1820 frame) 1852 (or (< best-diff-2-new best-diff-2)
1853 (and (= best-diff-2-new best-diff-2)
1854 (if (eq direction 'above)
1855 (> w-top best-edge-2)
1856 (< w-top best-edge-2)))))
1857 (setq best-edge-2 w-top)
1858 (setq best-diff-2 best-diff-2-new)
1859 (setq best-2 w)))))
1860 frame nil (and mini t))
1821 (or best best-2))) 1861 (or best best-2)))
1822 1862
1823(defun get-window-with-predicate (predicate &optional minibuf all-frames default) 1863(defun get-window-with-predicate (predicate &optional minibuf all-frames default)