From ed56da8c5b52c052ec3fdbf5e0b04b2040ca59d6 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Mon, 20 Jul 2026 16:05:15 -0500 Subject: fix(agenda): keep the agenda frame a single full-height agenda window The frame spawned with the working buffer in its top quarter and the agenda below at 75%. The sticky setting inside the F custom command applies too late to name the buffer, so it rendered as plain *Org Agenda*, and that name matches the 0.75 below-selected display rule in org-agenda-config.el, which split the brand-new frame. I bind org-agenda-sticky and current-window dynamically around the render, so the buffer is *Org Agenda(F)* (no display rule matches it) and it takes the frame's sole window. A delete-other-windows after the render is the belt in case any future rule still splits. The frame is also named "Full Agenda" now so it's recognizable at a glance and WM rules can target it. --- tests/test-org-agenda-frame.el | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/test-org-agenda-frame.el b/tests/test-org-agenda-frame.el index 19dab74b..c29d057b 100644 --- a/tests/test-org-agenda-frame.el +++ b/tests/test-org-agenda-frame.el @@ -772,11 +772,50 @@ Guards against restoring by raw line number after the item moved." side by side with the working frame), carrying the marker and a distinct name." (let ((params (cj/--agenda-frame-make-parameters))) (should (assq cj/--agenda-frame-parameter params)) - (should (equal (cdr (assq 'name params)) "Org Agenda")) + (should (equal (cdr (assq 'name params)) "Full Agenda")) ;; No fullscreen request -- a fullboth frame would cover the whole output ;; instead of tiling beside the working frame. (should-not (assq 'fullscreen params)))) +(ert-deftest test-org-agenda-frame-spawn-binds-sticky-and-current-window () + "Normal: spawn dynamically binds sticky + current-window around the render. +The custom command's own settings apply too late to name the buffer, so +without these bindings the buffer is plain *Org Agenda* -- which matches +the 0.75 below-selected display rule and splits the new frame with the +working buffer left on top." + (let (seen-sticky seen-setup) + (cl-letf (((symbol-function 'selected-frame) (lambda () 'launch)) + ((symbol-function 'make-frame) (lambda (&rest _) 'af)) + ((symbol-function 'select-frame-set-input-focus) (lambda (_f &rest _) nil)) + ((symbol-function 'cj/build-org-agenda-list) (lambda (&rest _) nil)) + ((symbol-function 'org-agenda) + (lambda (&rest _) + (setq seen-sticky org-agenda-sticky + seen-setup org-agenda-window-setup))) + ((symbol-function 'delete-other-windows) (lambda (&rest _) nil)) + ((symbol-function 'cj/--agenda-frame-sticky-buffer) (lambda () nil)) + ((symbol-function 'cj/--agenda-frame-start-timer) (lambda (_f) nil))) + (cj/--agenda-frame-spawn) + (should (eq seen-sticky t)) + (should (eq seen-setup 'current-window))))) + +(ert-deftest test-org-agenda-frame-spawn-forces-single-window () + "Boundary: spawn collapses the frame to one window after rendering. +A display rule that still splits the frame must not leave a second window +showing the launch buffer." + (let (collapsed) + (cl-letf (((symbol-function 'selected-frame) (lambda () 'launch)) + ((symbol-function 'make-frame) (lambda (&rest _) 'af)) + ((symbol-function 'select-frame-set-input-focus) (lambda (_f &rest _) nil)) + ((symbol-function 'cj/build-org-agenda-list) (lambda (&rest _) nil)) + ((symbol-function 'org-agenda) (lambda (&rest _) nil)) + ((symbol-function 'delete-other-windows) + (lambda (&rest _) (setq collapsed t))) + ((symbol-function 'cj/--agenda-frame-sticky-buffer) (lambda () nil)) + ((symbol-function 'cj/--agenda-frame-start-timer) (lambda (_f) nil))) + (cj/--agenda-frame-spawn) + (should collapsed)))) + (ert-deftest test-org-agenda-frame-spawn-starts-timer () "Normal: a successful spawn starts the refresh timer for the new frame." (let (timed) -- cgit v1.2.3