<feed xmlns='http://www.w3.org/2005/Atom'>
<title>dotemacs/modules/dashboard-config.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-06-05T10:28:58+00:00</updated>
<entry>
<title>feat(term): replace vterm with ghostel as the terminal engine</title>
<updated>2026-06-05T10:28:58+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-05T10:28:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=ebdf9e466b0e1f86e9b7d76650ac32408273e7a7'/>
<id>urn:sha1:ebdf9e466b0e1f86e9b7d76650ac32408273e7a7</id>
<content type='text'>
I swapped the terminal engine from vterm to ghostel (libghostty-vt) everywhere. term-config replaces vterm-config (the F12 terminal, the C-; x menu, tmux history capture), and ai-term replaces ai-vterm (the F9 Claude-agent launcher). ghostel renders the agent TUI without vterm's flicker under heavy streaming, and one engine now covers every terminal workflow.

Two behavior changes fall out of the swap. F9 launches in a terminal frame now: ghostel renders in TTY frames, so the old GUI-only guard is gone. Terminal windows no longer dim when unfocused: ghostel resolves its palette into the native module per-terminal, so there's no per-window color hook to dim through the way vterm had.

auto-dim drops its vterm color-advice path, the dashboard Terminal button launches ghostel, and the vterm and vterm-toggle packages are removed. The tmux pane-history and copy-mode machinery carried over unchanged. It keys on the pty tty, which ghostel exposes.
</content>
</entry>
<entry>
<title>fix(dashboard): exempt the banner buffer from auto-dim</title>
<updated>2026-05-26T12:47:03+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-26T12:47:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=35b5739e791965c837c2e715076b52d3fee9e156'/>
<id>urn:sha1:35b5739e791965c837c2e715076b52d3fee9e156</id>
<content type='text'>
The butterfly banner is a transparent PNG. On this X11 build Emacs composites image alpha against one background color and caches the flat pixmap. So when auto-dim remaps a non-selected dashboard's background to near-black, the cached image keeps its old composite and the transparent edges show as a lighter rectangle.

I exempted the *dashboard* buffer from dimming through the fork's never-dim-buffer hook, so its background never shifts. Live alpha compositing would need a pgtk build, which is out because of its fractional-scaling input lag, and every theme-level workaround changes dimming for all buffers. Scoping the exemption to one short-lived buffer is the narrow fix. The trade is no focus cue when the dashboard is shown in a split.

I also dropped the :mask heuristic prop from the prior banner commit. The PNG already carries a real alpha channel, so heuristic masking was the wrong tool. Once the background is stable, the native alpha over the theme background reads clean on its own. I added Normal/Boundary/Error tests for the predicate.
</content>
</entry>
<entry>
<title>feat(dashboard): render the butterfly banner with a transparency mask</title>
<updated>2026-05-25T18:15:21+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-25T18:15:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=4586325327b4b1ad5885c91437a774e45332657a'/>
<id>urn:sha1:4586325327b4b1ad5885c91437a774e45332657a</id>
<content type='text'>
The dashboard banner showed the butterfly PNG without its transparency, because the image descriptor was built before the mask props were set. I moved the banner setup (dashboard-startup-banner, dashboard-banner-logo-title) ahead of dashboard-setup-startup-hook and added dashboard-image-extra-props with :mask heuristic, so the mask is in place when the startup hook builds the buffer. If a *dashboard* buffer already exists I refresh it, so the change shows without a restart.

I also re-encoded the PNG smaller and kept the previous encoding as M-x_butterfly.png.bak.
</content>
</entry>
<entry>
<title>docs(load-graph): classify UI and core-UX modules</title>
<updated>2026-05-24T21:28:07+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-24T21:28:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=e1789025131b048049777542a91fb7eb55195ce5'/>
<id>urn:sha1:e1789025131b048049777542a91fb7eb55195ce5</id>
<content type='text'>
Fourth classification batch: the modules that shape the first interactive frame — ui-config, ui-theme, ui-navigation, font-config, selection-framework, modeline-config, mousetrap-mode, popper-config, dashboard-config, nerd-icons-config. I annotated each header, added a Batch 4 table to the inventory, and extended the validation allowlist. 33 of 102 modules are now classified.

These mostly stay eager: each has a real first-frame reason (theme, font, modeline, completion stack, landing page). No new hidden dependencies. popper-config carries the spec's open question about its enabled/disabled state, noted for the deferral phase.
</content>
</entry>
<entry>
<title>refactor(linear): point config at the renamed pearl package</title>
<updated>2026-05-24T12:45:14+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-24T12:45:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=c858c74aa09667fbf899f587be816e8ad5e20d55'/>
<id>urn:sha1:c858c74aa09667fbf899f587be816e8ad5e20d55</id>
<content type='text'>
The linear-emacs package was renamed to pearl (~/code/pearl, feature pearl, all symbols pearl-*). Swapped every linear-emacs-* reference to pearl-* across linear-config.el (the use-package form, :load-path, the 26 :commands, the api-key/default-team-id/org-file-path vars, and the lazy-key advice targets pearl--graphql-request-async and pearl-check-setup), the dashboard launcher, and the two test files.

Kept the Linear-domain naming intact, since pearl is just a client for the Linear service: the C-; L prefix, the cj/linear-* wrapper helpers, the "Linear" dashboard label, the api.linear.app authinfo host, and the data/linear.org synced file are unchanged. Verified the wiring in a live daemon — pearl loads, the team id and org-file path apply, and the key advice installs on both entry points.
</content>
</entry>
<entry>
<title>feat(dashboard): add a Linear launcher and group the navigator by row sizes</title>
<updated>2026-05-24T05:03:39+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-24T05:03:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=835c2d3a4bd3f695889911edd7a9681c38ff8581'/>
<id>urn:sha1:835c2d3a4bd3f695889911edd7a9681c38ff8581</id>
<content type='text'>
I added a Linear entry to the launcher table, keyed l, with the nf-oct-issue_tracks octicon, opening the issue list via linear-emacs-list-issues. That makes 13 launchers, which no longer divides into the old rigid 4-per-row grid.

So I replaced the fixed chunk-by-4 with an explicit cj/dashboard--row-sizes (4 4 3 2) and reordered the table so Telegram comes before Slack, putting Slack and Linear together on the last row. The button shape moved into cj/dashboard--navigator-button, shared by the grouped loop and a fallback row for any launchers the sizes don't cover. A test pins the row sizes to the launcher count so they can't drift.
</content>
</entry>
<entry>
<title>refactor(dashboard): derive the navigator and keybindings from one launcher table</title>
<updated>2026-05-23T00:00:36+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-23T00:00:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=5c160bd5f33b0e27ecac32af99f650ea50d844fe'/>
<id>urn:sha1:5c160bd5f33b0e27ecac32af99f650ea50d844fe</id>
<content type='text'>
The 12 dashboard launchers were inlined twice (once as navigator icon buttons, once as dashboard-mode-map keybindings), so adding or reordering one meant editing both lists, and the icon-row order could drift from the key order.

I pulled them into a single cj/dashboard--launchers table of (KEY ICON-FN ICON-NAME LABEL TOOLTIP ACTION) tuples. cj/dashboard--navigator-rows chunks it four per row into the navigator buttons, and cj/dashboard--bind-launchers binds each key to its action. The icons and the keys now come from one place, with no behavior change: same icons, labels, order, and keys, locked by tests.
</content>
</entry>
<entry>
<title>fix(dashboard): center the banner subtitle and color the navigator and items</title>
<updated>2026-05-22T23:15:00+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-22T23:15:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=11e3a27e752e845e583348c497b2c5b0208c8a52'/>
<id>urn:sha1:11e3a27e752e845e583348c497b2c5b0208c8a52</id>
<content type='text'>
The banner subtitle sat left of center because dashboard-banner-title-offset was 5, which over-shifts. I dropped it to 3, which lines the subtitle up under the banner image.

The navigator and the recentf/project/bookmark list rendered in the default near-white. I set dashboard-items-face to steel+2 so they pick up a theme color, and the section headers stay blue via dashboard-heading. The navigator and the items share dashboard-items-face, because the navigator is drawn with a dashboard-items-face overlay that wins over its per-button dashboard-navigator face, so they take one color by design here.
</content>
</entry>
<entry>
<title>fix(dashboard): trim padding newlines and reset window-start on open</title>
<updated>2026-05-21T02:23:29+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-21T02:23:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=4ac1b8161f7206592fa3d8efbf7eabb5c51b7bc6'/>
<id>urn:sha1:4ac1b8161f7206592fa3d8efbf7eabb5c51b7bc6</id>
<content type='text'>
The dashboard often opened already scrolled: content sat partly above the visible window with empty lines stranded at the bottom. There were two causes. The startupify list inserted five padding newlines that pushed the content past one screenful, and cj/dashboard-only moved point to point-min without resetting window-start, so a previously-scrolled view leaked into the next display.

I trimmed the padding to one newline after the banner title and one before the items, and added a set-window-start to point-min in cj/dashboard-only so the view always starts at the top. A characterization test locks the window-start reset.
</content>
</entry>
<entry>
<title>refactor(dashboard): regroup launcher icons into 4/4/4 by purpose</title>
<updated>2026-05-14T19:13:20+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-14T19:13:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=2a4637b401a3e47547edc21641512633647df35f'/>
<id>urn:sha1:2a4637b401a3e47547edc21641512633647df35f</id>
<content type='text'>
Telegram had landed alone on a third row of one icon, with the
first two rows holding a mixed bag (Code next to Email next to
Agenda next to Files next to Music; Feeds next to IRC next to
Slack next to Flashcards next to Books next to Terminal).  No
category showed up grouped, and the asymmetry was bugging me
every dashboard open.

Regroup by what the icons actually do.  Three rows of four:

- Row 1 Work:           Code   / Files       / Terminal / Agenda
- Row 2 Read &amp; Learn:   Feeds  / Books       / Flashcards / Music
- Row 3 Communication:  Email  / IRC         / Slack     / Telegram

Reorder the `define-key' calls on `dashboard-mode-map' to mirror
the row layout -- reading the keymap top-to-bottom now matches
reading the icons left-to-right.

Drive-by fix in the same commit: Music had an icon but no
`dashboard-mode-map' keybinding (mouse-only).  Bound to `m'.
</content>
</entry>
</feed>
