<feed xmlns='http://www.w3.org/2005/Atom'>
<title>dotemacs/tests/test-org-agenda-frame.el, branch main</title>
<subtitle>My Emacs configuration
</subtitle>
<id>https://git.cjennings.net/dotemacs/atom?h=main</id>
<link rel='self' href='https://git.cjennings.net/dotemacs/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/'/>
<updated>2026-07-20T21:55:58+00:00</updated>
<entry>
<title>feat(agenda): suspend auto-dim while the agenda frame is open</title>
<updated>2026-07-20T21:55:58+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-20T21:55:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=8a00b8809a9f9c79cb4354736c205c841f27fb25'/>
<id>urn:sha1:8a00b8809a9f9c79cb4354736c205c841f27fb25</id>
<content type='text'>
The refresh tick's selection swing marks the working window non-selected, and auto-dim's debounced dim lands after the tick, so the working frame visibly dimmed every five minutes. Spawn now turns auto-dim-other-buffers-mode off (remembering it was on) and closing the frame restores it. A spawn with auto-dim already off touches nothing. It also keeps the standing agenda fully lit instead of dimmed-when-unfocused.
</content>
</entry>
<entry>
<title>fix(agenda): hide the refresh tick's selection flicker</title>
<updated>2026-07-20T21:42:32+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-20T21:42:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=da6ab4174ae8bb404b6740edd7ec437c20b822bd'/>
<id>urn:sha1:da6ab4174ae8bb404b6740edd7ec437c20b822bd</id>
<content type='text'>
The rebuild takes a second or two, and for its whole duration the agenda window was the selected window, so the cursor visibly went hollow in the working frame on every tick. It read as focus theft, though no focus function ever ran. The tick now inhibits redisplay (the synchronous rebuild blocks Emacs anyway, so this costs nothing) and restores selection before redisplay resumes. A tick that would fire during an active minibuffer is skipped.
</content>
</entry>
<entry>
<title>fix(agenda): repair the refresh tick, tighten the gutter, allow point motion</title>
<updated>2026-07-20T21:22:49+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-20T21:22:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=c7e551f28a6cb410ed05c3a8f867c70672927b94'/>
<id>urn:sha1:c7e551f28a6cb410ed05c3a8f867c70672927b94</id>
<content type='text'>
Every 5-minute refresh failed. The F command's general settings carried (org-agenda-sticky t), and those settings are baked into the buffer's series-redo-cmd and re-applied on each redo. With the buffer already existing, org-agenda-use-sticky-p turned true mid-redo and org-agenda-prepare threw 'exit ("use r to refresh") to a catch that doesn't exist inside org-agenda-redo. I removed sticky from the command settings (the spawn wrapper still binds it, which is where the buffer gets its name) and kept the redo path free of sticky, since org-agenda-redo handles the in-place rebuild itself. Verified with a real tick against a live frame: rebuild succeeds, the failure banner clears, the latch resets.

The wide gutter between the source column and the item was the global agenda prefix format's 25-char category pad. The F view now sets its own format with a 10-char pad.

C-a hit the deny catch-all. I allowlisted read-only point motion (C-a, C-e, C-f, C-b) and isearch (C-s, C-r).
</content>
</entry>
<entry>
<title>fix(agenda): keep the agenda frame a single full-height agenda window</title>
<updated>2026-07-20T21:05:15+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-20T21:05:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=ed56da8c5b52c052ec3fdbf5e0b04b2040ca59d6'/>
<id>urn:sha1:ed56da8c5b52c052ec3fdbf5e0b04b2040ca59d6</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>fix(agenda): make C-x C-c close the agenda frame, not the daemon</title>
<updated>2026-07-20T20:56:56+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-20T20:56:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=d11f3d5a18271ffd8e4b9822988ccc2fd2e0bcde'/>
<id>urn:sha1:d11f3d5a18271ffd8e4b9822988ccc2fd2e0bcde</id>
<content type='text'>
The catch-all denied it before, and letting the global through would be worse: save-buffers-kill-terminal on a make-frame frame has no client to close, so it kills the daemon. Inside the frame the gesture now runs the frame close.
</content>
</entry>
<entry>
<title>fix(agenda): stop the frame's catch-all from swallowing input machinery</title>
<updated>2026-07-20T20:52:24+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-20T20:52:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=db9353837def65e627cc1dac5c343789d660aa2d'/>
<id>urn:sha1:db9353837def65e627cc1dac5c343789d660aa2d</id>
<content type='text'>
The default-deny [t] binding intercepted far more than Org commands. switch-frame events hit the deny handler, so every focus change into or out of the frame spammed the read-only message and broke frame switching. Mouse wheel, mouse-1 clicks, and the help prefix were dead. And S-&lt;f8&gt;/C-M-&lt;f8&gt; were never bound in the mode map, so the frame's own toggle couldn't close it from inside.

I punched the machinery through the catch-all (an explicit nil shadows the [t] default in the same map, so those events fall through to their global bindings) and bound the two frame controls per the spec's allowlist.

Two redo-lifecycle bugs rode along, both from org-agenda-mode's kill-all-local-variables: the buffer-local kill-buffer-hook was stripped on the first refresh tick (killing the buffer would orphan the frame), and the failure banner was held in a buffer-local var while its overlay survives erase-buffer, so a banner could never be removed after a later success. The finalize re-enable now re-adds the hook, and the banner is tagged with an overlay property and found by scanning.
</content>
</entry>
<entry>
<title>fix(agenda): spawn the agenda frame tiled, not compositor-fullscreen</title>
<updated>2026-07-20T20:38:23+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-20T20:38:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=1ccd7bddf55c41202afe316e70fa01059e1bcbbb'/>
<id>urn:sha1:1ccd7bddf55c41202afe316e70fa01059e1bcbbb</id>
<content type='text'>
I dropped (fullscreen . fullboth) from the spawned frame so a tiling WM places it side by side with the working frame. "Fullscreen" was the wrong word for the intent: a normal frame at its full tiled position, not one covering the whole output. The engage-routing and focus logic are unchanged and matter more now, since a task opens in the adjacent working pane.
</content>
</entry>
<entry>
<title>feat(agenda): add S-&lt;f8&gt; dedicated fullscreen agenda frame</title>
<updated>2026-07-20T19:23:38+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-20T19:23:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=404590623599398f120cd73d44ad235271c3b5bd'/>
<id>urn:sha1:404590623599398f120cd73d44ad235271c3b5bd</id>
<content type='text'>
I added a standing agenda surface in its own fullscreen frame of the daemon, placeable on its own workspace while the working frames stay untouched. S-&lt;f8&gt; spawns, raises, or closes it. The force-rescan moves to C-M-&lt;f8&gt;.

It shows a today-anchored seven-day view and refreshes every five minutes through org-agenda-redo, so the now-line and synced events stay current without re-scanning the file list. A default-deny minor mode keeps it read-only: only navigation, the engage keys (routed to the working frame), and the frame's own controls are allowed. A failed redo falls back to the last-good snapshot with cloned markers, so the frame is never blank or unrestricted.

I made it a frame of the daemon rather than a second process, so it shares the live state (calendar-sync, edits, the now-line). There's no startup auto-open, and the Hyprland-managed-window variant is a vNext once this proves out.
</content>
</entry>
</feed>
