==== On themes, sway, emacs and kitty - the dark-mode script ====
Unlike Desktop Environments like Gnome and KDE, Window Managers like
**sway** do not come with all the tools you might need or want. It's up to
the user to perceive a need, do the research and then install,
configure and use the appropriate tools for the job. Notwithstanding
the earnest attempts by the DE's to bury the implementation details in
obscure code and non-existent documentation, this approach gives me a
lean and mean working environment albeit not as pretty. Plus the
satisfaction of knowing what's going on.
In my own history through **fvwm**, **fluxbox**, **i3wm** and now **sway** I've never
really wanted to bother with themes. I just made terminals and emacs
have a black background and other programs could do what ever they
liked. Such a heathen!
Recently I felt that need and did some research into the
topic. It was rather more complex and harder to discover than I had
thought.
I wanted to have a simple switch I could flick, perhaps a
script, that would turn night into day. Let's have black text on a
bright, white background in the daytime and reverse it in the evening.
I wanted to have the changes applied to running programs without
restarting them.
Sounds simple? Here are some notes on what I discovered for
customising and a script that I use to do the flick.
All of this is on Fedora-31 but should be similar for other Linux distros.
Apologies if this is all obvious and well documented elsewhere. It was a journey for me and non-trivial.
===GTK2 programs===
GTK2 programs start up referring to ''~/.gtkrc-2.0'' for their theme
hints. Simple really, just lob in a new value:
''gtk-theme-name="Adwaita"''
or
''gtk-theme-name="Adwaita-dark"''
The hard part was understanding how to get running programs to notice
the change. ''**lxappearance**(1)'' is a program from the LXDE desktop
environment that does both jobs. Unfortunately, it lacks a CLI
interface so it can only be used in the pointy-clicky mode and not in
a script.
By using ''**strace**(1)'' on the different components, I was able to track this
down to a new (for me) system call ''**eventfd**(2)'' which GTK2 uses as a
signalling mechanism. With a bit more research I found this script
fragment at [[https://crunchbang.org/forums/viewtopic.php?id=39646]] which
invokes the correct event in the GTK2 world and makes those programs
re-read ''~/.gtkrc-2.0'':
#!/usr/bin/python2
import sys, gtk
events=gtk.gdk.Event(gtk.gdk.CLIENT_EVENT)
data=gtk.gdk.atom_intern("_GTK_READ_RCFILES", False)
events.data_format=8
events.send_event=True
events.message_type=data
events.send_clientmessage_toall()''
===GTK3 programs===
GTK3 programs start up referring to ''~/.config/gtk-3.0/settings.ini''
but the format is slightly different (of course!)
''gtk-theme-name=Adwaita-dark''
Note the cunning change in the use of quotation marks.
Again, getting programs that are already running to notice the change
is lightly documented, if at all. But I found that by installing
gnome-settings-daemon (a bit of an overkill for my lightweight
purposes) there is a daemon that can do the job. So I added this to my
sway config:
''exec /usr/libexec/gsd-xsettings''
I just wonder if this could be replaced by a simple script like the
GTK2 one?
But that appears to be not the entire story.
===dconf===
Some programs do not respond to gsd-xsettings and dconf is needed:
dconf write /org/gnome/desktop/interface/gtk-theme "'Adwaita-dark'"
Again, note the amusing change in quotation - single quotes are
essential. The dconf approach also appears to work for live GTK2
programs and overrides the value in ''~/.gtkrc-2.0'' and
''~/.config/gtk-3.0/settings.ini''
===gsettings===
More comedy arises from yet another path to the same outcome. This
invocation appears to be completely equivalent with it's own
permutation on the quotation merry-go-around:
gsettings set org.gnome.desktop.interface gtk-theme Adwaita-dark
===emacs===
''**emacs**(1)''. Hmmm. I've grown up with that program and am unlikely to
wean myself off it. There are 'PureGTK' versions floating around as
experiments but they are yet to hit the Fedora repositories outside
COPR so I haven't tried them to see how they respond to the standard
GTK signals.
In any case, for ''**emacs**(1)'' I need to also modify the internal text areas
and ''**emacs**(1)'' has its own themes spelled out in elisp. I decided on a
couple of good themes and added some code to my script to flip from
one theme to another. The script should be self explanatory. The
themes I chose were a modified dichromacy (for the colourblind) and a
derived dichromacy-dark which I created by 'inverting' the original
using a script at [[https://explog.in/notes/poet.html#monochrome]]
===kitty===
Now for my favorite wayland terminal emulator, ''**kitty**(1)''. It has it's
own unique configuration language and can have its colour changed on
the fly like this:
kitty @ set_colors --all foreground=white background=black
===bash===
My ''**bash**(1)'' prompt contains colours and I have a separate script
(actually a function in ''~/.bashrc'') that responds appropriately to the
setting of ''TERM_BACKGROUND'' in {dark,light} so my script outputs that
setting and invokes setup_prompt.
eval $( dark-mode on )
... 'dark-mode on' outputs ''TERM_BACKGROUND=dark; setup_prompt'' and
that's what gets eval'd.
These final 2 steps are the reason I don't put ''**dark-mode**(1)'' into a cron
job - it needs to run in my stack of ''**kitty**(1)'' terminal tabs.
===KDE===
KDE/Qt5/Plasma/whatcha-ma-call-it
Thanks to redditor r/progandy for this:
''**qt5ct**(1)'' is the key - install it (Fedora) with:
sudo dnf install qt5ct
This needs to be in the session environment:
export QT_QPA_PLATFORMTHEME=qt5ct
After running ''**qt5ct**(1)'' I now have a ''~/.config/qt5ct/qt5ct.conf'' file that contains a line:
style=Adwaita
... I can hit that with my script and the qt5 programs automatically change their appearance!
Oddly, there's a 4s delay after changing the style in the file before the new style takes effect. But that's OK.
I also built [[https://gitlab.com/zetaPRIME/qt5ct-refresh|qt5ct-refresh]] but it doesn't seem to speed up the 4s delay - or do anything AFAICT.
===dark-mode===
Here is the result of all this rambling: https://gitlab.com/wef/dotfiles/-/blob/master/bin/dark-mode