[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Understanding after-make-frame-functions

From: Kaushal Modi
Subject: Re: Understanding after-make-frame-functions
Date: Tue, 17 May 2016 18:08:43 +0000

On Tue, May 17, 2016 at 12:37 PM Eli Zaretskii <> wrote:

> What Emacs does during startup is documented in the ELisp manual, see
> the node "Startup Summary".  If you have specific suggestions for
> amendments there, please file a bug report with those suggestions.

I had already gone through that but it does not talk about the nuance that
in daemon mode case, the frame is created after the window-setup-hook is
run; whereas it is created before evaluating the init in the case of
non-daemon mode. The side effect of that on after-make-frame-functions hook
being useful only for daemon cases is also not mentioned anywhere.

The above-mentioned node in the manual describes more hooks, so maybe
> you should simply use a different hook for your needs.

Thanks! I had already gone through the list of startup hooks in (elisp)
Standard Hooks node. I went through it once again and figured out that
focus-in-hook is what I need (the only drawback being that hook is called
each time a frame gets in focus, not just at startup. And for that reason,
I didn't even consider using it. But now I am, as shown after the below
test snippet).

I updated my test snippet to add the debug statement to focus-in-hook too!

(defvar my-index 1
  "Index that increments after each hook is called.")
(dolist (hook '(before-init-hook
  (add-hook hook
            `(lambda (&optional frame)
               (message "[%d] Running `%s' .."
                        my-index (symbol-name (quote ,hook)))
               (message "[%d]  Symbola: %S"
                        my-index (find-font (font-spec :name "Symbola")))
               (setq my-index (1+ my-index))) :append))

Based on what I learned, I updated the font check code to below:
(defun modi/font-check (&optional frame)
  "Do font-check; require `setup-font-check' just once."
  (unless (featurep 'setup-font-check)
    (require 'setup-font-check)))
(add-hook 'focus-in-hook #'modi/font-check)

Explanation for the above:
 For non-daemon, regular emacs launches, the frame/fonts are loaded *before*
 the emacs config is read. But when emacs is launched as a daemon (using
 emacsclient, the fonts are not actually loaded until the point when the
 `after-make-frame-functions' hook is run. But even at that point, the frame
 is not yet selected (for the daemon case). Without a selected frame, the
 `find-font' will not work correctly. So we do the font check in
 `focus-in-hook' instead by which all the below are true:
  - Fonts are loaded (in both daemon and non-daemon cases).
  - The frame is selected and so `find-font' calls work correctly.

I would suggest moving the code to a hook that runs later, when the
> initial frame is already the selected one.

Looks like focus-in-hook is the next one available when the frame is

> Not sure, but if there's specific information you'd like to be there,
> let's talk specifics.

I do not know what's the correct terminology to be used for "user emacs
config", "daemon mode" and "non-daemon mode" in documentation, but the idea
for after-make-frame-functions documentation is as below:

Functions to run after a frame is created.
The functions are run with one arg, the newly created frame.

In daemon mode (emacs --daemon or emacsclient), the frame is created at
some point after the `window-setup-hook' is run (after the user emacs
config is evaluated). So this hook is called _after_ the user config

But in the non-daemon mode, the frame is created before the user emacs
config is evaluated. So this hook is run before that, and so any user
customization done to this hook would be ineffective in the non-daemon case.


Kaushal Modi

reply via email to

[Prev in Thread] Current Thread [Next in Thread]