diff options
| author | Craig Jennings <c@cjennings.net> | 2026-08-25 05:28:25 -0600 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-08-25 05:28:25 -0600 |
| commit | 638310601a39e7f9ade59ea85794a21167905f31 (patch) | |
| tree | 59ebb07880634aaf2084cf4917b09aadc1cd7068 /modules/system-defaults.el | |
| parent | ac1d034d09dd37305e84d08438fef268ed8173bc (diff) | |
| download | dotemacs-638310601a39e7f9ade59ea85794a21167905f31.tar.gz dotemacs-638310601a39e7f9ade59ea85794a21167905f31.zip | |
fix(startup): keep *Warnings* alive so 31.1's first frame is Wayland
Emacs 31.1's warnings.el defers daemon-startup warnings into a one-shot after-make-frame-functions closure that holds the *Warnings* buffer object and displays it on the first client frame. The startup sweep in cj/dashboard-only killed that buffer first. On the first emacsclient -c of every session, display-buffer then signaled inside make-frame and server.el answered -window-system-unsupported. emacsclient silently retried on $DISPLAY, and the frame opened on XWayland behind the pgtk "unsupported under X" dialog. Only that first frame was affected, which made it look like a display problem rather than a config one.
I added *Warnings* to cj/undead-buffer-list so the sweep buries it instead, the same choice desktop.el makes in desktop-clear-preserve-buffers. Two things follow. C-x k on *Warnings* now buries it. A startup that produced warnings shows them on the first frame, because the deferred closure finally has a live buffer. As a backstop, cj/warning--display-buffer-if-live wraps warning--display-buffer so a dead buffer (or a name that resolves to none) is skipped rather than passed on. That function only exists from Emacs 31, and advising the undefined symbol on 30.2 is harmless.
The new tests pin *Warnings* to the undead list and check the sweep leaves it live. The guard tests cover live and dead buffers plus names that do and don't resolve, and run the real 31.x function on a dead buffer.
Diffstat (limited to 'modules/system-defaults.el')
| -rw-r--r-- | modules/system-defaults.el | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/modules/system-defaults.el b/modules/system-defaults.el index d9ec1878..47bd1505 100644 --- a/modules/system-defaults.el +++ b/modules/system-defaults.el @@ -89,6 +89,30 @@ indicate the warning was handled." (advice-add 'display-warning :before-until #'cj/log-comp-warning) +;; ------------------ Deferred Daemon Warnings vs. Frame Creation ----------------- + +;; Emacs 31's warnings.el defers warnings raised during daemon startup: it puts +;; a one-shot closure on `after-make-frame-functions' holding the *Warnings* +;; buffer object and calls `warning--display-buffer' on it when the first +;; client frame is made. If that buffer died in between, `display-buffer' +;; signals inside `make-frame', server.el reports "-window-system-unsupported", +;; and emacsclient retries on $DISPLAY -- the first frame of the session +;; silently opens on XWayland. Keeping *Warnings* alive is the root fix +;; (undead-buffers.el); this guard is the backstop, so no future buffer sweep +;; can break frame creation the same way. The function only exists from +;; Emacs 31; advising an undefined symbol is harmless and takes effect once +;; warnings.el defines it. + +(defun cj/warning--display-buffer-if-live (orig buffer) + "Call ORIG with BUFFER only when it names or is a live buffer. +Around advice for `warning--display-buffer'. BUFFER may be a buffer object +or a buffer name, like `display-buffer' accepts. Return nil when skipped." + (let ((buf (and buffer (get-buffer buffer)))) + (when (buffer-live-p buf) + (funcall orig buf)))) + +(advice-add 'warning--display-buffer :around #'cj/warning--display-buffer-if-live) + ;; ---------------------------------- Unicode ---------------------------------- (set-locale-environment "en_US.UTF-8") |
