toggle_theme script
This literate configuration for setting and toggling theme in swaywm is maintained in org mode . org-babel tangles this to ~/.config/sway/scripts/toggle_theme↗ , available as part of dotfiles .
The :tangle-mode (identity #o755) is added to the header args. Otherwise every tangle will reset the permissions and the script permission needs to be changed everytime to make it an executable.
Initialization
Let any reference to an unset variable become a fatal error.
#!/bin/sh
set -u
Variables
Define light and dark theme names and config paths for Sway, Foot etc..
DARK_THEME="Nordic"
LIGHT_THEME="Adwaita"
SWAY_CONFIG_DIR="$HOME/.config/sway"
SWAY_THEMES_DIR="$SWAY_CONFIG_DIR/themes"
SWAY_DARK_CONFIG="$SWAY_THEMES_DIR/nord.conf"
SWAY_LIGHT_CONFIG="$SWAY_THEMES_DIR/adwaita.conf"
GTK3_CONFIG="$HOME/.config/gtk-3.0/settings.ini"
FOOT_THEMES_DIR="$HOME/.config/foot/themes"
FOOT_DARK_CONFIG="$FOOT_THEMES_DIR/dark.ini"
FOOT_LIGHT_CONFIG="$FOOT_THEMES_DIR/light.ini"
FOOT_CURRENT_LINK="$HOME/.config/foot/current_theme.ini"
Helper Functions
Setting theme for different applications or components of a desktop is handled by their respective helper functions. These helper functions are invoked by the theme setting functions.
Foot terminal
The theme toggle script requires few changes in the foot configuration file . It needs an include section and necessary theme files for the toggle script to work. We reset the symbolic file link for current theme using the force option to overwrites existing link. These settings are effective only for new terminals as the config file is read once at process start.
For changing the theme of existing foot terminals, signals 1 and 2 are sent as per documentation. For the signals to work, need to include [colors-dark] and [colors-light] sections.
apply_foot_theme() {
local theme_file="$1"
if [ -f "$theme_file" ]; then
ln -sf "$theme_file" "$FOOT_CURRENT_LINK"
fi
}
Gtk applications
The gsetting based command to update D-Bus works only for modern gtk apps. For legacy apps, we update the physical config file.
apply_gtk_theme() {
local theme=$1
local color_scheme=$2
gsettings set org.gnome.desktop.interface gtk-theme "$theme"
gsettings set org.gnome.desktop.interface color-scheme "$color_scheme"
if [ -f "$GTK3_CONFIG" ]; then
sed -i "s/^gtk-theme-name=.*/gtk-theme-name=$theme/" "$GTK3_CONFIG"
fi
}
Sway
Similar to foot, we reset the symbolic file link for current theme using the force option to overwrite existing link. This is also logged to system log.
apply_sway_theme() {
local theme_file="$1"
local target="$SWAY_CONFIG_DIR/current_theme.conf"
if [ -f "$theme_file" ]; then
ln -sf "$theme_file" "$target"
swaymsg reload
logger "Symlinked $theme_file to $target"
fi
}
Dark theme
The order of applying theme was choosen based on the response time of each option.
prabu@homepc2 ~> time gsettings set org.gnome.desktop.interface gtk-theme Nordic
________________________________________________________
Executed in 40.58 millis fish external
usr time 17.67 millis 1.53 millis 16.14 millis
sys time 6.99 millis 0.02 millis 6.97 millis
prabu@homepc2 ~> time gsettings set org.gnome.desktop.interface color-scheme prefer-dark
________________________________________________________
Executed in 37.77 millis fish external
usr time 16.97 millis 0.71 millis 16.25 millis
sys time 9.69 millis 1.03 millis 8.65 millis
prabu@homepc2 ~> time swaymsg reload
________________________________________________________
Executed in 356.76 millis fish external
usr time 0.69 millis 0.69 millis 0.00 millis
sys time 2.91 millis 1.03 millis 1.88 millis
Since swaymsg reload takes the longest time, it is applied at the end.
set_dark_theme() {
echo "Switching to dark theme ($DARK_THEME)..."
apply_foot_theme "$FOOT_DARK_CONFIG"
pkill -SIGUSR1 foot
apply_gtk_theme "$DARK_THEME" "prefer-dark"
apply_sway_theme "$SWAY_DARK_CONFIG"
}
Light theme
set_light_theme() {
echo "Switching to light theme ($LIGHT_THEME)..."
apply_foot_theme "$FOOT_LIGHT_CONFIG"
pkill -SIGUSR2 foot
apply_gtk_theme "$LIGHT_THEME" "prefer-light"
apply_sway_theme "$SWAY_LIGHT_CONFIG"
}
Default theme
Always initialize with dark theme. This option is invoked in sway config file. The option ${1:-} means “use $1 if it’s set, otherwise substitute an empty string”.
if [ "${1:-}" = "init" ]; then
logger "Sway Init: Forcing dark theme"
set_dark_theme
exit 0
fi
Toggle logic
The toggle logic fetches the current theme from gsettings to toggle the theme.
CURRENT_GTK_THEME=$(gsettings get org.gnome.desktop.interface gtk-theme)
CURRENT_GTK_THEME=$(echo "$CURRENT_GTK_THEME" | tr -d "'")
if [ "$CURRENT_GTK_THEME" = "$DARK_THEME" ]; then
set_light_theme
else
set_dark_theme
fi
© Prabu Anand K 2020-2026