Dark theme in Emacs

01 May, 2016

GNOME and GTK+ supports using a dark theme that's quite easy on the eyes. This is usually an opt-in for applications, but you can also force it. The easiest way to do this is to enable global dark themes in gnome-tweak-tool.

There is however another (admittedly hacky) way to do this on a per application basis and quite easy to make it work well in Emacs:

Emacs with dark theme

A dark Emacs goes very well with the Tango color theme by Julien Barnier.

The first step is to launch emacs with the 'GTK_THEME' set to dark, like so: ´GTK_THEME=Adwaita:dark´ . Just wrap it in a simple shell script.

Launching Emacs like that will however give an unsightly non-dark window manager. We can use the xprop utility to force a dark variant.

xprop -f _GTK_THEME_VARIANT 8u -set _GTK_THEME_VARIANT "dark"

You could even wrap that in a shell function that uses wmctrl to get the window id instead of clicking on the emacs window each time.

A neater way to accomplish the same is to run it within emacs. We can even have it run each time a new frame is created:

WARNING: Some really ugly Elisp follows, be gentle, it's my first time...

(defun set-dark-wm-theme (frame)
  (select-frame frame) ;; this is important!
  (when (display-graphic-p)
      (when (file-exists-p "/usr/bin/xprop")
      (defvar winid nil)
      (setq winid (frame-parameter frame 'outer-window-id))
      (call-process "xprop" nil nil nil "-f" "_GTK_THEME_VARIANT" "8u" "-set" "_GTK_THEME_VARIANT" "dark" "-id" winid))))))

(defun on-after-init ()
  (set-dark-wm-theme (selected-frame))
  (unless (display-graphic-p (selected-frame))
    (set-face-background 'default "unspecified-bg" (selected-frame))))

(add-hook 'window-setup-hook 'on-after-init)

(add-hook 'after-make-frame-functions 'set-dark-wm-theme)

This is a pretty convoluted setup, but was a fun excuse to poke around Emacs hooks and write some Elisp.