aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/org-agenda-frame.el21
-rw-r--r--tests/test-org-agenda-frame.el41
2 files changed, 57 insertions, 5 deletions
diff --git a/modules/org-agenda-frame.el b/modules/org-agenda-frame.el
index ef541c2f..efd74115 100644
--- a/modules/org-agenda-frame.el
+++ b/modules/org-agenda-frame.el
@@ -31,6 +31,8 @@
;; `with-eval-after-load' so a batch test-load runs no org-agenda side effects.
(defvar org-agenda-custom-commands)
(defvar org-agenda-finalize-hook)
+(defvar org-agenda-sticky)
+(defvar org-agenda-window-setup)
(declare-function cj/build-org-agenda-list "org-agenda-config" (&optional force-rebuild))
(declare-function cj/org-agenda-refresh-files "org-agenda-config" ())
(declare-function org-agenda-redo "org-agenda" (&optional all))
@@ -357,10 +359,11 @@ the timer and kills the sticky buffer."
"Return the frame parameters for the dedicated agenda frame.
A normal frame -- not fullscreen -- so a tiling window manager places it
side by side with the working frame rather than covering the whole output.
-It carries the `cj/agenda-frame' marker and a distinct name so window-manager
-rules can target it."
+It carries the `cj/agenda-frame' marker and a distinct, noticeable name
+\(\"Full Agenda\") so the frame is recognizable at a glance and
+window-manager rules can target it."
`((,cj/--agenda-frame-parameter . t)
- (name . "Org Agenda")))
+ (name . "Full Agenda")))
(defun cj/--agenda-frame-spawn ()
"Create, display, and focus the dedicated agenda frame.
@@ -378,7 +381,17 @@ Returns the new agenda frame on success."
;; Cached, non-forced: a frame spawned early after daemon startup
;; still shows the full project agenda, not the base-files-only view.
(cj/build-org-agenda-list)
- (org-agenda "a" cj/--agenda-frame-command-key)
+ ;; Bind sticky + current-window dynamically around the render. The
+ ;; custom command's own settings apply too late to name the buffer;
+ ;; without these the buffer is plain *Org Agenda*, which matches the
+ ;; 0.75 below-selected display rule in org-agenda-config.el -- the
+ ;; new frame gets split with the launch buffer left in the top 25%.
+ ;; Sticky names it *Org Agenda(F)*, which no display rule matches.
+ (let ((org-agenda-sticky t)
+ (org-agenda-window-setup 'current-window))
+ (org-agenda "a" cj/--agenda-frame-command-key))
+ ;; Belt: whatever a display rule did, the frame is one agenda window.
+ (delete-other-windows)
(let ((buffer (cj/--agenda-frame-sticky-buffer)))
(when (buffer-live-p buffer)
(with-current-buffer buffer
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)