dotfiles/.scripts/theme-changer.sh

361 lines
9.2 KiB
Bash
Executable file

#!/bin/bash
albums_dir="$HOME/Images/Wallpapers/Desktop"
declare -A albums=(
[sfw]="$albums_dir/SFW"
[nsfw]="$albums_dir/( ͡° ͜ʖ ͡°)"
[bonk]="$albums_dir/Bonk"
[hypr]="/usr/share/hyprland/wall0.png"
)
# Declare outside of function to make them global.
declare -A colors
declare -A params
function show_help {
cat << EOF
Usage: $(basename "$0") ACTION
ACTION:
a, album ALBUM_NAME[,ALBUM_NAME] Select a random wallpaper from one or more albums & change the theme.
h, help Show this help.
l, list List all defined albums.
r, reload Reload the current theme.
w, wallpaper WP_PATH Change the theme using a specific wallpaper.
EOF
}
function check_requirements {
req_satisfied=1
for executable in hyprctl hyprpaper kitty magick mako pastel wal waybar wlogout wofi; do
if ! which "$executable" > /dev/null; then
echo "Executable $executable not found!"
req_satisfied=0
fi
done
if [ $req_satisfied -eq 0 ]; then
echo "Missing some requirements, exiting."
exit 1
fi
}
function list_albums {
echo "Defined albums:"
for album in "${!albums[@]}"; do
echo " $album: ${albums[$album]}"
done
}
# Transform comma separated $albums_arg into array ${target_albums[@]}
function parse_albums_arg {
IFS=', ' read -r -a target_albums <<< "$albums_arg"
# Check if entered album(s) are valid.
for target_album in "${target_albums[@]}"; do
if ! echo "${!albums[@]}" | grep -qP "\b$target_album\b"; then
echo "Invalid album name, exiting."
exit 1
fi
done
}
# Pick a random wallpaper from ${target_albums[@]}
function pick_random_wallpaper {
declare -a target_dirs
for target_album in "${target_albums[@]}"; do
target_dirs+=("${albums[$target_album]}")
done
echo "Picking a random wallpaper from ${target_dirs[*]}."
wallpaper="$(find "${target_dirs[@]}" -type f -regex '.*\.\(jpg\|jpeg\|png\)$' | shuf -n 1)"
# Reassign to make variable global.
wallpaper="$wallpaper"
}
function set_theme {
echo "Selected wallpaper: $wallpaper"
# Generate the colors scheme
echo "Generating color scheme using pywal."
wal -qni "$wallpaper" --saturate 0.75
# Replace apostrophes around the wallpaper path with quotes
# in case there is an apostrophe in the file name
sed -iE "/^wallpaper=/,/#/ s/='/=\"/" "$HOME/.cache/wal/colors.sh"
sed -iE "/^wallpaper=/,/#/ s/'$/\"/" "$HOME/.cache/wal/colors.sh"
# Source colors scheme generated
source "$HOME/.cache/wal/colors.sh"
set_theme_variables
set_gtk_css_file
for component in desktop_wallpaper hyprland kitty mako pywalfox waybar wlogout wofi; do
set_${component}_theme &
done
}
function set_theme_variables {
# Set colors
accent1_dark_hsl="$(pastel darken 1 "$color5" | pastel format hsl)"
accent2_dark_hsl="$(pastel darken 1 "$color6" | pastel format hsl)"
colors=(
[foreground]="$foreground"
[good]="#00BB66"
[bad]="#AA2222"
[urgent]="$color4"
[accent1]="$color5"
[accent2]="$color6"
[background1]="$(pastel lighten 0.2 "$accent1_dark_hsl" | pastel format hex)"
[background2]="$(pastel lighten 0.2 "$accent2_dark_hsl" | pastel format hex)"
[hovered]="$(pastel lighten 0.25 "$accent1_dark_hsl" | pastel format hex)"
[selected]="$(pastel lighten 0.35 "$accent1_dark_hsl" | pastel format hex)"
[disabled]="$(pastel lighten 0.35 "$accent1_dark_hsl" | pastel format hex)"
[disabled2]="$(pastel lighten 0.35 "$accent2_dark_hsl" | pastel format hex)"
)
params=(
[border_radius]=4
[border_size]=2
[gaps_out]=15
[gaps_in]=8
[font]="'JetBrainsMono NF'"
)
}
function set_gtk_css_file {
mkdir -p "$HOME/.config/gtk-3.0" &> /dev/null
echo -n '' > "$HOME/.config/gtk-3.0/colors.css"
for key in "${!colors[@]}"; do
value="${colors[$key]}"
echo "@define-color $key $value;" >> "$HOME/.config/gtk-3.0/colors.css"
done
}
function set_betterdiscord_theme {
if which betterdiscordctl > /dev/null; then
echo "Executable found for betterdiscordctl."
if [[ ! -f "$HOME/.config/BetterDiscord/data/stable/custom.css" ]]; then
echo "Downloading ClearVision theme for BetterDiscord."
mkdir -p "$HOME/.config/BetterDiscord/data/stable"
wget -O "$HOME/.config/BetterDiscord/data/stable/custom.css" "https://betterdiscord.app/Download?id=23"
fi
echo "Changing BetterDiscord theme colors."
declare -A bd_variables=(
[main-color]="${colors[accent1]}"
[hover-color]="${colors[accent2]}"
[text-normal]="${colors[foreground]}"
[background-shading]='0%'
[background-overlay]='rgba(0, 0, 0, 0)'
[background-image]="linear-gradient(160deg, ${colors[background1]}, ${colors[background2]})"
)
for key in "${!bd_variables[@]}"; do
value="${bd_variables[$key]}"
sed -i "s~--$key:[^;]*~--$key: $value~" "$HOME/.config/BetterDiscord/data/stable/custom.css"
done
else
echo "No executable found for betterdiscordctl, skipping."
fi
}
function set_desktop_wallpaper_theme {
if ! pgrep -u "$USER" hyprpaper > /dev/null; then
hyprctl -q dispatch exec hyprpaper
while ! hyprctl -q hyprpaper listloaded; do
sleep 0.1
done
fi
for monitor in $(hyprctl -j monitors | jq -r '.[] | .name'); do
hyprctl -q hyprpaper preload "$wallpaper"
hyprctl -q hyprpaper wallpaper "$monitor,$wallpaper"
if [[ -n $albums_arg ]]; then
# Sets global variable $wallpaper
pick_random_wallpaper
fi
done
hyprctl -q hyprpaper unload unused
}
function set_hyprland_theme {
echo -n '' > "$HOME/.config/hypr/hyprland.d/colors.conf"
for key in "${!colors[@]}"; do
value="${colors[$key]}"
echo '$'"$key=rgb(${value:1})" >> "$HOME/.config/hypr/hyprland.d/colors.conf"
done
for key in "${!params[@]}"; do
value="${params[$key]}"
echo '$'"$key=$value" >> "$HOME/.config/hypr/hyprland.d/colors.conf"
done
hyprctl -q reload
}
function set_kitty_theme {
declare -A kitty_variables=(
[font_family]="${params[font]}"
[url_color]="${colors[accent1]}"
[tab_bar_background]="${colors[background1]}"
[active_tab_background]="${colors[selected]}"
[inactive_tab_background]="${colors[hovered]}"
[active_tab_foreground]="${colors[foreground]}"
[inactive_tab_foreground]="${colors[foreground]}"
)
for key in "${!kitty_variables[@]}"; do
value="${kitty_variables[$key]}"
sed -i "s/^$key.*/$key $value/" "$HOME/.config/kitty/kitty.conf"
done
killall -SIGUSR1 kitty &> /dev/null
}
function set_mako_theme {
declare -A mako_variables=(
[font]="${params[font]} 11"
[border-radius]="${params[border_radius]}"
[border-size]="${params[border_size]}"
[outer-margin]="$((params[gaps_out]*2)),$((params[gaps_out]*2)),0,0"
[text-color]="${colors[foreground]}"
[background-color]="${colors[background1]}"
[border-color]="${colors[accent1]}"
)
for key in "${!mako_variables[@]}"; do
value="${mako_variables[$key]}"
sed -i "s/$key=.*/$key=$value/" "$HOME/.config/mako/config"
done
if pgrep -u "$USER" mako > /dev/null; then
makoctl reload
else
hyprctl -q dispatch exec mako
fi
}
function set_openrgb_theme {
if which openrgb > /dev/null; then
openrgb --noautoconnect -c "${colors[accent1]:1}" > /dev/null
fi
}
function set_pywalfox_theme {
if pgrep -u "$USER" firefox &> /dev/null; then
pywalfox update
fi
}
function set_waybar_theme {
declare -A waybar_variables=(
[font-family]="${params[font]}"
[border-bottom]="${params[border_size]}px solid transparent"
[margin-bottom]="${params[border_size]}px"
)
for key in "${!waybar_variables[@]}"; do
value="${waybar_variables[$key]}"
sed -i "s~$key:[^;]*~$key: $value~" "$HOME/.config/waybar/style.css"
done
if pgrep -u "$USER" waybar > /dev/null; then
killall -SIGUSR2 waybar
else
hyprctl -q dispatch exec waybar
fi
}
function set_wlogout_theme {
for img in lock reboot shutdown logout; do
magick "$HOME/.config/wlogout/$img.png" -fill "${colors[accent1]}" -colorize 100 "$HOME/.config/wlogout/$img.png"
magick "$HOME/.config/wlogout/$img-focus.png" -fill "${colors[accent2]}" -colorize 100 "$HOME/.config/wlogout/$img-focus.png"
done
}
function set_wofi_theme {
declare -A wofi_variables_window=(
[font-family]="${params[font]}"
[border]="${params[border_size]}px solid transparent"
[border-radius]="${params[border_radius]}px"
)
for key in "${!wofi_variables_window[@]}"; do
value="${wofi_variables_window[$key]}"
sed -i "/^window/,/$key:/ s~$key:[^;]*~$key: $value~" "$HOME/.config/wofi/style.css"
done
declare -A wofi_variables_input=(
[margin]="${params[border_size]}px"
[border-radius]="${params[border_radius]}px ${params[border_radius]}px 0 0"
)
for key in "${!wofi_variables_input[@]}"; do
value="${wofi_variables_input[$key]}"
sed -i "/^#input/,/$key:/ s~$key:[^;]*~$key: $value~" "$HOME/.config/wofi/style.css"
done
# Set entry:selected border-radius
sed -i "/^#entry:selected/,/border-radius:/ s/border-radius:[^;]*/border-radius: $(( params[border_radius]/2 ))px/" "$HOME/.config/wofi/style.css"
}
check_requirements
case "$1" in
a|album)
albums_arg="$2"
parse_albums_arg
pick_random_wallpaper
set_theme
;;
h|help)
show_help
;;
l|list)
list_albums
;;
r|reload)
# Get the current wallpaper in $wallpaper
source "$HOME/.cache/wal/colors.sh"
set_theme
;;
w|wallpaper)
wallpaper="$2"
check_wallpaper_path
set_theme
;;
*)
show_help
exit 1
;;
esac