rolandwalker / unicode-fonts

Configure Unicode fonts for Emacs
227 stars 28 forks source link

Initializing under daemon? #3

Open yurikhan opened 11 years ago

yurikhan commented 11 years ago

The readme says use (unicode-fonts-setup) in the init file. When starting Emacs as daemon, this is executed but has no effect. Afterwards, running an emacsclient -c . opens an X frame, with fonts at their defaults.

What do I need to hook so that (unicode-fonts-setup) is run for X frames created for emacsclient?

yurikhan commented 11 years ago

I have tried:

When I start the first client frame, they run with (window-system) returning nil, so calling (unicode-fonts-setup) has no effect.

arbelt commented 11 years ago

It's probably not the most elegent solution, but I use an after-make-frame-functions hook that removes itself after it runs successfully (on a graphical frame where fonts are available)

(defun my/init-fonts (&optional f)
  (when (display-graphic-p f)
    (unicode-fonts-setup)
    ;; anything else that needs fonts to be available
    (remove-hook 'after-make-frame-functions 'my/init-fonts))))

(add-hook 'after-init-hook
          (lambda ()
            (if initial-window-system
                (my/init-fonts)
              (add-hook 'after-make-frame-functions 'my/init-fonts))))

the after-init-hook is there is there in case emacs was not started as a daemon -- the after-frame-functions are not run on the first frame, so this just says run my/init-fonts explicitly instead of adding it as a frame hook.

yurikhan commented 11 years ago

Nice. I wonder if it’s worthwhile deferring until after-init-hook. The initial frame is already created when init files are parsed, so I’m inclined to try running the hook right then.

yurikhan commented 11 years ago

Some more observations.

I worked around this by sticking a (select-frame f) immediately before (unicode-fonts-setup).

The resulting snippet looks like this:

(defun my/init-fonts (&optional frame)
  (when (display-graphic-p frame)
    (select-frame frame)
    (unicode-fonts-setup)
    (remove-hook 'after-make-frame-functions 'my/init-fonts)))
(add-hook 'after-init-hook
          (lambda ()
            (if initial-window-system
                (my/init-fonts)
              (add-hook 'after-make-frame-functions 'my/init-fonts))))
arbelt commented 11 years ago

Ah, good catch! I've just started trying out unicode-fonts and hadn't actually put it in the hook when I posted (just what I was using previously for set-fontset-font commands). I ran into the same problem when I did, and your fix solves it perfectly.

rolandwalker commented 11 years ago

Is there a proposed patch?

yurikhan commented 11 years ago

So far, we were just discussing workarounds. But I can prepare a patch that (a) fixes the “record that we have run but actually do nothing”, and/or (b) passes the frame as a parameter to unicode-fonts-setup, and/or (c) puts this whole snippet into the library, exposing it under the original name of unicode-fonts-setup (with appropriate renaming). Which way would you like?

arbelt commented 11 years ago

One quick note: since frame is an optional argument, the call should be wrapped to accommodate non-daemon startup: (when frame (select-frame frame))

rolandwalker commented 11 years ago

I don't use daemon startup, so I'm inclined to take the advice of those that do so on how the fix should be implemented. The purpose of the library is purely convenience, so the goal should be that (unicode-fonts-setup) would work as documented even if the user uses --daemon.

yurikhan commented 10 years ago

Hello,

another user is now in the same position as I was a year and a half ago.

I have updated the pull request #4 to the current master.

rolandwalker commented 10 years ago

Hi!

Thanks for reviving. I forgot about this issue as I don't use --daemon startup and never got around to trying it. I will try out #4.

Reading that Google Plus thread, I want to note that unicode-fonts startup is much faster now. If the user is seeing a five-second cost, he should upgrade.

guraltsev commented 9 years ago

I have emacs 24.4.1 with unicode-fonts 20150223.1059 from melpa. I still have the problem that unicode-fonts-setup. to solve it I used the solution inspired by the G+ post:

 (defun my-hook-unicode-fonts-setup (frame)
    "Run unicode-fonts-setup, then remove the hook."
    (progn
      (select-frame frame)
      (unicode-fonts-setup)
      (message "Removing unicode-fonts-setup to after-make-frame-functions hook")
      (remove-hook 'after-make-frame-functions 'my-hook-unicode-fonts-setup)
      ))

  (add-hook 'after-make-frame-functions 'my-hook-unicode-fonts-setup nil)

Otherwise it does not work.

bradrn commented 3 years ago

I’ve run into the same issue, five years later. @guraltsev’s code snippet solved the problem for me. I suggest this should be integrated into the package somehow.

samwdp commented 2 years ago

Is there any news on this. I have tried using the comment from @guraltsev and I have also installed used the 'fix-daemon-startup' branch from @yurikhan and that hasn't helped. This may be todo with the org-superstar plugin though

lebensterben commented 2 years ago
(use-package unicode-fonts
  :init (unicode-fonts//setup-fonts (selected-frame)))

(defun unicode-fonts//setup-fonts (frame)
  "Setup `unicode-fonts' package for FRAME.

This functions setups `unicode-fonts' right away when starting a GUI Emacs.
But if Emacs is running in a daemon, it postpone the setup until a GUI frame
is opened."
  (if (and frame (display-graphic-p frame))
      (with-selected-frame frame
        (require 'unicode-fonts)
        (unicode-fonts-setup)
        (remove-hook 'after-make-frame-functions #'unicode-fonts//setup-fonts))
    (add-hook 'after-make-frame-functions #'unicode-fonts//setup-fonts)))

I've come up with this solution. If people can verify it I will make a PR.

eslgastal commented 1 year ago

Based on the info in this thread, I've implemented the following macro in my config, which seems to work:

(require 'cl)

(setq my/run-once-after-first-frame-counter 0)

(defmacro my/run-once-after-first-frame (&rest body)
  `(lexical-let* (target-hook
                  (count my/run-once-after-first-frame-counter)
                  (fnsymb (make-symbol (format "my/run-once-after-first-frame-%d" count))))
     (setq target-hook (if (daemonp)
                           'after-make-frame-functions
                         'after-init-hook))
     (fset fnsymb (lambda (&optional frame)
                    (remove-hook target-hook fnsymb)
                    (when frame (select-frame frame))
                    ,@body))
     (add-hook target-hook fnsymb)
     (cl-incf my/run-once-after-first-frame-counter)))

Usage example:

(my/run-once-after-first-frame
 (unicode-fonts-setup)
 ;; Other commands go here, such as load-theme, etc...
)

Also solves other problems such as this one.