I tried patching with -(daemonp) +(and (daemonp) (= (length (visible-frame-list)) 1)) Then I killed the daemon, leaving a .lock behind. On restart: - In a tty, I get a black screen with a blinking cursor on the bottom left corner. If I press 'y', it proceeds with loading the desktop file. I can verify that from the *Messages* buffer. - With EXWM, I get a black screen, but 'y' does not work. So it's effectively stuck. I'm thinking that maybe `after-make-frame-functions' are run too early, before the frame is fully ready. Then I re-considered Eli's last remark: the daemon already has a frame, so I thought maybe we should also guard the hook with a check on the frames count: (defun ambrevar/desktop-init (_frame) (when (> (length (visible-frame-list)) 1) (desktop-save-mode) (desktop-read) (remove-hook 'after-make-frame-functions 'ambrevar/desktop-init))) That did not change anything. Any clue?