fix(popup): find internal major side windows

Fix: #5485
This commit is contained in:
Tim Ruffing 2023-12-24 02:25:56 +01:00 committed by Henrik Lissner
parent fcf63d615a
commit dca4e4a8ed
2 changed files with 21 additions and 8 deletions

View file

@ -505,11 +505,22 @@ Accepts the same arguments as `display-buffer-in-side-window'. You must set
((not (numberp vslot)) ((not (numberp vslot))
(error "Invalid vslot %s specified" vslot))) (error "Invalid vslot %s specified" vslot)))
(let* ((major (get-window-with-predicate (let* ((live (get-window-with-predicate
(lambda (window) (lambda (window)
(and (eq (window-parameter window 'window-side) side) (and (eq (window-parameter window 'window-side) side)
(eq (window-parameter window 'window-vslot) vslot))) (eq (window-parameter window 'window-vslot) vslot)))
nil)) nil))
;; As opposed to the `window-side' property, the `window-vslot'
;; property is set only on a single live window and never on internal
;; windows. Moreover, as opposed to `window-with-parameter' (as used
;; by the original `display-buffer-in-side-window'),
;; `get-window-with-predicate' only returns live windows anyway. In
;; any case, we will have missed the major side window and got a
;; child instead if the major side window happens to be an internal
;; window. In that case, the major side window is the parent of the
;; live window.
(major (and live
(if (window-next-sibling live) (window-parent live) live)))
(reversed (window--sides-reverse-on-frame-p (selected-frame))) (reversed (window--sides-reverse-on-frame-p (selected-frame)))
(windows (windows
(cond ((window-live-p major) (cond ((window-live-p major)

View file

@ -44,14 +44,14 @@
:to-contain '(size . 5))))) :to-contain '(size . 5)))))
(describe "popup rules" (describe "popup rules"
:var (origin a b c d e f g) :var (origin a b c d e f g h i)
(before-all (setq origin (current-buffer))) (before-all (setq origin (current-buffer)))
(before-each (before-each
(dolist (name '(a b c d e f g)) (dolist (name '(a b c d e f g h i))
(set name (get-buffer-create (symbol-name name))))) (set name (get-buffer-create (symbol-name name)))))
(after-each (after-each
(let (kill-buffer-query-functions kill-buffer-hook) (let (kill-buffer-query-functions kill-buffer-hook)
(dolist (x (list a b c d e f g)) (dolist (x (list a b c d e f g h i))
(ignore-errors (delete-window (get-buffer-window x))) (ignore-errors (delete-window (get-buffer-window x)))
(kill-buffer x)))) (kill-buffer x))))
@ -64,11 +64,13 @@
("d" :slot 2 :vslot 2) ("d" :slot 2 :vslot 2)
("e" :slot 1 :vslot 3) ("e" :slot 1 :vslot 3)
("f" :slot 1 :vslot 3) ("f" :slot 1 :vslot 3)
("g")))) ("g" :slot 2 :vslot 3)
("h" :slot 2 :vslot 3)
("i"))))
(it "replaces popups with the same slots" (it "replaces popups with the same slots"
(mapc #'display-buffer (list e f)) (mapc #'display-buffer (list e f g h))
(expect (length (+popup-windows)) :to-be 1)) (expect (length (+popup-windows)) :to-be 2))
(it "replaces popups among multiple that have the same slots" (it "replaces popups among multiple that have the same slots"
(let ((first (display-buffer a)) (let ((first (display-buffer a))
@ -92,7 +94,7 @@
(expect (window-in-direction 'right first t) (expect (window-in-direction 'right first t)
:to-equal second))) :to-equal second)))
(it "obeys default :slot" (it "obeys default :slot"
(let ((window (display-buffer g))) (let ((window (display-buffer i)))
(expect (window-parameter window 'window-slot) :to-be 1) (expect (window-parameter window 'window-slot) :to-be 1)
(expect (window-parameter window 'window-vslot) :to-be 1)))) (expect (window-parameter window 'window-vslot) :to-be 1))))