diff --git a/modules/ui/popup/autoload/popup.el b/modules/ui/popup/autoload/popup.el index 46bd5e2f0..27880b432 100644 --- a/modules/ui/popup/autoload/popup.el +++ b/modules/ui/popup/autoload/popup.el @@ -505,11 +505,22 @@ Accepts the same arguments as `display-buffer-in-side-window'. You must set ((not (numberp vslot)) (error "Invalid vslot %s specified" vslot))) - (let* ((major (get-window-with-predicate + (let* ((live (get-window-with-predicate (lambda (window) (and (eq (window-parameter window 'window-side) side) (eq (window-parameter window 'window-vslot) vslot))) 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))) (windows (cond ((window-live-p major) diff --git a/modules/ui/popup/test/test-popup.el b/modules/ui/popup/test/test-popup.el index 945f5a937..569e3ebbc 100644 --- a/modules/ui/popup/test/test-popup.el +++ b/modules/ui/popup/test/test-popup.el @@ -44,14 +44,14 @@ :to-contain '(size . 5))))) (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-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))))) (after-each (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))) (kill-buffer x)))) @@ -64,11 +64,13 @@ ("d" :slot 2 :vslot 2) ("e" :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" - (mapc #'display-buffer (list e f)) - (expect (length (+popup-windows)) :to-be 1)) + (mapc #'display-buffer (list e f g h)) + (expect (length (+popup-windows)) :to-be 2)) (it "replaces popups among multiple that have the same slots" (let ((first (display-buffer a)) @@ -92,7 +94,7 @@ (expect (window-in-direction 'right first t) :to-equal second))) (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-vslot) :to-be 1))))