diff options
| author | Martin Rudalics | 2013-12-13 18:06:30 +0100 |
|---|---|---|
| committer | Martin Rudalics | 2013-12-13 18:06:30 +0100 |
| commit | 71e6691e5c9347f53fc984ccba83065c5e9fabaf (patch) | |
| tree | 25c303c98309f4df2dbfd0e1eeef781ef98a3bda | |
| parent | 5035fbc19e2f569674237c61e6ffdd4719e092d5 (diff) | |
| download | emacs-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/ChangeLog | 10 | ||||
| -rw-r--r-- | lisp/windmove.el | 37 | ||||
| -rw-r--r-- | lisp/window.el | 106 |
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 @@ | |||
| 1 | 2013-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 | |||
| 1 | 2013-12-13 Dmitry Gutov <dgutov@yandex.ru> | 11 | 2013-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 | |||
| 438 | to. DIR is one of `left', `up', `right', or `down'; an optional ARG | 438 | to. DIR is one of `left', `up', `right', or `down'; an optional ARG |
| 439 | is handled as by `windmove-reference-loc'; WINDOW is the window that | 439 | is handled as by `windmove-reference-loc'; WINDOW is the window that |
| 440 | movement is relative to." | 440 | movement 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. |
| 468 | DIR, ARG, and WINDOW are handled as by `windmove-other-window-loc'." | 466 | DIR, 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. |
| 1724 | More precisely, return the nearest window in direction DIRECTION | 1724 | More precisely, return the nearest window in direction DIRECTION |
| 1725 | as seen from the position of `window-point' in window WINDOW. | 1725 | 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. | |||
| 1732 | If, however, the optional argument IGNORE is non-nil, return that | 1732 | If, however, the optional argument IGNORE is non-nil, return that |
| 1733 | window even if its `no-other-window' parameter is non-nil. | 1733 | window even if its `no-other-window' parameter is non-nil. |
| 1734 | 1734 | ||
| 1735 | Optional argument SIGN a negative number means to use the right | ||
| 1736 | or bottom edge of WINDOW as reference position instead of | ||
| 1737 | `window-point'. SIGN a positive number means to use the left or | ||
| 1738 | top edge of WINDOW as reference position. | ||
| 1739 | |||
| 1740 | Optional argument WRAP non-nil means to wrap DIRECTION around | ||
| 1741 | frame borders. This means to return for a WINDOW a the top of | ||
| 1742 | the frame and DIRECTION `above' to return the minibuffer window | ||
| 1743 | if the frame has one, and a window at the bottom of the frame | ||
| 1744 | otherwise. | ||
| 1745 | |||
| 1746 | Optional argument MINI nil means to return the minibuffer window | ||
| 1747 | if and only if it is currently active. MINI non-nil means to | ||
| 1748 | return the minibuffer window even when it's not active. However, | ||
| 1749 | if WRAP non-nil, always act as if MINI were nil. | ||
| 1750 | |||
| 1735 | Return nil if no suitable window can be found." | 1751 | Return 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) |