2022-01-02
when i press super+shift+p, my computer toggles between a light and dark color palette.
~/.config/i3/config
bindsym $mod+Shift+p exec "$HOME/bin/i3-toggle-palette"
~/bin/i3-toggle-palette
#!/bin/sh
set -x
current=$(basename $(readlink $HOME/.config/palette) .palette)
case $current in
dark) next=light ;;
light) next=dark ;;
*)
echo "unhandled '$current'"
exit 1
;;
esac
$HOME/bin/set-palette $next
the file ~/.config/palette is a symlink managed by set-palette.
~/bin/set-palette
#!/bin/sh
set -x
set -e
set -u
set -o pipefail
if [ -f "$HOME/.config/$1.palette" ]
then
ln -s -f "$HOME/.config/$1.palette" "$HOME/.config/palette"
else
echo "palette '$1' does not exist"
exit 1
fi
# Hack Firefox's dark theme. New preferences are read after all firefox
# processes are terminated.
if [ "$1" = light ]
then
echo 'user_pref("ui.systemUsesDarkTheme", 0);' > ~/.mozilla/firefox/evlmnjjl.default-default-1-1599517563999/user.js
else
echo 'user_pref("ui.systemUsesDarkTheme", 1);' > ~/.mozilla/firefox/evlmnjjl.default-default-1-1599517563999/user.js
fi
$HOME/bin/reload-colors reload
each palette is a shell script that sets some variables. i spend the majority of my time in a terminal, so i decided to focus my palette on the “4-bit” ANSI terminal palette.
~/.config/light.palette
#!/bin/sh
# various shades of pink
COLOR_PRIMARY_00=#b88888
COLOR_PRIMARY_01=#f3bac0
COLOR_PRIMARY_02=#ffd0d3
COLOR_PRIMARY_03=#ffeeea
COLOR_MONO_00=#111111
COLOR_MONO_01=#333333
COLOR_MONO_02=#dddddd
COLOR_MONO_03=#fffff8
COLOR_BLACK_00=#111111
COLOR_BLACK_01=#333333
COLOR_RED_00=#ff0f24
COLOR_RED_01=#f23e41
COLOR_GREEN_00=#19cb00
COLOR_GREEN_01=#509d26
COLOR_YELLOW_00=#dfb200
COLOR_YELLOW_01=#9f7e24
COLOR_YELLOW_01=#ffff00
COLOR_BLUE_00=#0e3bf8
COLOR_BLUE_01=#485ede
COLOR_MAGENTA_00=#ff00e6
COLOR_MAGENTA_01=#d44acb
COLOR_CYAN_00=#2ec0c0
COLOR_CYAN_01=#799b9b
COLOR_WHITE_00=#dddddd
COLOR_WHITE_01=#fffff8
COLOR_BG=$COLOR_MONO_03
COLOR_FG=$COLOR_MONO_00
once set-palette switches the symlink, i reload everything i know how to reload.
~/bin/reload-colors
#!/bin/sh
set -ex
$HOME/bin/reload-xrdb
$HOME/bin/kitty-colors-from-xrdb > $HOME/.config/kitty/colors.conf
if [ "$1" = reload ]
then
i3 reload
for sock in /tmp/kitty*.sock
do
kitty @ --to=unix:$sock set-colors -a -c $HOME/.config/kitty/colors.conf
done
fi
in reload-xrdb, i render a template Xresources file with the palette. now that i think about it, this is kind of ridiculous! but it builds on things i configured many moons ago.
~/bin/reload-xrdb
#!/bin/sh
. $HOME/.config/palette
PIXELS_MEDIUM=14
PIXELS_LARGE=16
PIXELS_HUGE=48
xsetroot -solid $COLOR_PRIMARY_01
[ -f $HOME/.Xresources ] && xrdb \
-DFONT_FACE_REGULAR="Go Mono:antialias=true" \
-DPIXELS_MEDIUM=$PIXELS_MEDIUM \
-DPIXELS_LARGE=$PIXELS_LARGE \
-DPIXELS_HUGE=$PIXELS_HUGE \
-DCOLOR_PRIMARY_00=$COLOR_PRIMARY_00 \
-DCOLOR_PRIMARY_01=$COLOR_PRIMARY_01 \
-DCOLOR_PRIMARY_02=$COLOR_PRIMARY_02 \
-DCOLOR_PRIMARY_03=$COLOR_PRIMARY_03 \
-DCOLOR_BG=$COLOR_BG \
-DCOLOR_FG=$COLOR_FG \
-DCOLOR_MONO_00=$COLOR_MONO_00 \
-DCOLOR_MONO_01=$COLOR_MONO_01 \
-DCOLOR_MONO_02=$COLOR_MONO_02 \
-DCOLOR_MONO_03=$COLOR_MONO_03 \
-DCOLOR_BLACK_00=$COLOR_BLACK_00 \
-DCOLOR_BLACK_01=$COLOR_BLACK_01 \
-DCOLOR_RED_00=$COLOR_RED_00 \
-DCOLOR_RED_01=$COLOR_RED_01 \
-DCOLOR_GREEN_00=$COLOR_GREEN_00 \
-DCOLOR_GREEN_01=$COLOR_GREEN_01 \
-DCOLOR_YELLOW_00=$COLOR_YELLOW_00 \
-DCOLOR_YELLOW_01=$COLOR_YELLOW_01 \
-DCOLOR_BLUE_00=$COLOR_BLUE_00 \
-DCOLOR_BLUE_01=$COLOR_BLUE_01 \
-DCOLOR_MAGENTA_00=$COLOR_MAGENTA_00 \
-DCOLOR_MAGENTA_01=$COLOR_MAGENTA_01 \
-DCOLOR_CYAN_00=$COLOR_CYAN_00 \
-DCOLOR_CYAN_01=$COLOR_CYAN_01 \
-DCOLOR_WHITE_00=$COLOR_WHITE_00 \
-DCOLOR_WHITE_01=$COLOR_WHITE_01 \
-load $HOME/.Xresources
xrdb -query
~/.Xresources
*foreground: COLOR_FG
*background: COLOR_BG
*color0: COLOR_BLACK_00
*color1: COLOR_RED_00
*color2: COLOR_GREEN_00
*color3: COLOR_YELLOW_00
*color4: COLOR_BLUE_00
*color5: COLOR_MAGENTA_00
*color6: COLOR_CYAN_00
*color7: COLOR_WHITE_00
*color8: COLOR_BLACK_01
*color9: COLOR_RED_01
*color10: COLOR_GREEN_01
*color11: COLOR_YELLOW_01
*color12: COLOR_BLUE_01
*color13: COLOR_MAGENTA_01
*color14: COLOR_CYAN_01
*color15: COLOR_WHITE_01
my.mono0: COLOR_MONO_00
my.mono1: COLOR_MONO_01
my.mono2: COLOR_MONO_02
my.mono3: COLOR_MONO_03
my.primary0: COLOR_PRIMARY_00
my.primary1: COLOR_PRIMARY_01
my.primary2: COLOR_PRIMARY_02
my.primary3: COLOR_PRIMARY_03
now that Xresources are reloaded, we can reload everything else and cause everything else to use the Xresources.
well, not everything likes to use Xresources. my terminal emulator of choice, kitty, uses yaml. thankfully the rewriting is not so bad!
~/bin/kitty-colors-from-xrdb
#!/bin/sh
echo "# This file was generated by
# $0 $@
# at $(date +%FT%R).
#
# xrdb -query | egrep '\*color' | sed -E -e 's/^\*//' -e 's/://'"
xrdb -query | egrep '\*(color|foreground|background)' | sed -E -e 's/^\*//' -e 's/://'
it took me a while to learn how to tell all kitty windows to reset their colors. i learned how to let kitty accept commands over a socket, and then i learned how to make all kitty windows share a single socket.
snippet of ~/bin/reload-colors
kitty @ --to=unix:$sock set-colors -a -c $HOME/.config/kitty/colors.conf
snippet of ~/.config/i3/config
#=> i3 config to make all kitty instances share a socket
bindsym $mod+Return exec /usr/local/bin/kitty --single-instance
bindsym $mod+d exec /usr/local/bin/rofi -show combi -combi-modi 'window#run#ssh' -modi combi -terminal '/usr/local/bin/kitty --single-instance'
kitty will also load the palette at startup.
snippet of ~/.config/kitty/kitty.conf
include colors.conf
i3 can derive configuration variables from Xresources.
snippet of ~/.config/i3/config
set_from_resource $color0 i3wm.color0 #ff0000
set_from_resource $color1 i3wm.color1 #ff0000
set_from_resource $color2 i3wm.color2 #ff0000
set_from_resource $color3 i3wm.color3 #ff0000
set_from_resource $color4 i3wm.color4 #ff0000
set_from_resource $color5 i3wm.color5 #ff0000
set_from_resource $color6 i3wm.color6 #ff0000
set_from_resource $color7 i3wm.color7 #ff0000
set_from_resource $color8 i3wm.color8 #ff0000
set_from_resource $color9 i3wm.color9 #ff0000
set_from_resource $color10 i3wm.color10 #ff0000
set_from_resource $color11 i3wm.color11 #ff0000
set_from_resource $color12 i3wm.color12 #ff0000
set_from_resource $color13 i3wm.color13 #ff0000
set_from_resource $color14 i3wm.color14 #ff0000
set_from_resource $color15 i3wm.color15 #ff0000
set_from_resource $mono0 my.mono0 #ff0000
set_from_resource $mono1 my.mono1 #ff0000
set_from_resource $mono2 my.mono2 #ff0000
set_from_resource $mono3 my.mono3 #ff0000
set_from_resource $primary0 my.primary0 #ff0000
set_from_resource $primary1 my.primary1 #ff0000
set_from_resource $primary2 my.primary2 #ff0000
set_from_resource $primary3 my.primary3 #ff0000
set $todo #ff0000
client.focused $color6 $primary3 $mono1 $color6 $color6
client.focused_inactive $color14 $primary3 $color14 $color14 $color14
client.unfocused $color14 $primary2 $color14 $color14 $color14
client.urgent $primary2 $color14 $primary2 $primary2 $primary2
client.placeholder $todo $color6 $todo $todo $todo
client.background $primary2
bar {
status_command i3status | $HOME/bin/myi3status
position top
colors {
background $primary2
statusline $mono1
separator $color14
focused_workspace $color6 $primary3 $mono1
inactive_workspace $color14 $primary2 $color14
urgent_workspace $primary2 $color14 $primary2
}
}
a simple
i3 reload
does the trick.
my scheme involves writing to an undocumented “user.js” file in a randomly-named directory. it also doesn’t work unless i restart firefox.
i didn’t find a programable way to change the lagrange theme, but i feel much better about the prospect of reading (and perhaps hacking) the codebase.i didn’t even try with claws-mail :) but perhaps i should just not be reading my email after sunset.