
Created a wrapper script to customize theme variables (colors, fonts, etc) according with your X resources file (~/.Xresources). As dunst is not a X exclusive notification daemon, this script could be a workarround to solve this. Related with: #357
256 lines
8.3 KiB
Bash
Executable File
256 lines
8.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
###############################################################################
|
|
##
|
|
## Usage
|
|
##
|
|
## ./<script_name> [<OPTIONS>]
|
|
##
|
|
## If it does not run, give execute permissions to the script with
|
|
## chmod +x <script_name>. Then run ./<script_name>.
|
|
##
|
|
## Options
|
|
##
|
|
## -h|--help Optional. Show help message.
|
|
##
|
|
## Description
|
|
##
|
|
## This script creates a dunst themed user config in $HOME/.config/dunst/
|
|
## folder, changing dunst basic theming options (like fonts, colors, etc.)
|
|
## according to your current X resources color palette.
|
|
##
|
|
## To make this possible, it reads your current user config
|
|
## ($HOME/.conf/dunst/dunstrc, which is copied from the default config if
|
|
## it does not exist) and changes the attributes values with new ones (see
|
|
## Theming section for more info). Then it dumps the new configuration to
|
|
## $user_xr_color_conf file.
|
|
##
|
|
## Theming
|
|
##
|
|
## To change colors and fonts:
|
|
##
|
|
## * Firstly you have to ensure that those dunst attributes are defined in
|
|
## the corresponding sections. For example, to change the frame_color
|
|
## value from the global section, in $HOME/.config/dunst/dunstrc should
|
|
## be:
|
|
##
|
|
## ...
|
|
## [global]
|
|
## ...
|
|
## frame_color = <value>
|
|
## ...
|
|
##
|
|
## * Then, you can change attribute values as you wish with the
|
|
## following format in theme_attr_dict:
|
|
##
|
|
## ["<sec>-<attr>"]="<val>|$(xrdb_get '<X_res>' '<dev_val>')"
|
|
##
|
|
## Each <variable> means the following:
|
|
##
|
|
## * sec - current section name e.g.: global.
|
|
## * attr - current attribute name e.g.: frame-color.
|
|
## * val - a simple value e.g.: "#fffeee", Monospace, 11...
|
|
## * X_res - X resource name e.g.: color8.
|
|
## * dev_val - default value to set if X_res is not found e.g.: #65737e.
|
|
##
|
|
## Theming example (you can check theme_attr_dict for other values):
|
|
##
|
|
## ["global-frame_color"]="\"$(xrdb_get 'color8' '#65737e')
|
|
##
|
|
## The function xrdb_get, searches the first parameter in the X resources
|
|
## database with appres (command installed from xorg-appres in archlinux
|
|
## and x11-utils in ubuntu). If the first parameter does not exist, the
|
|
## function returns the second parameter. For hex colors, is important to
|
|
## scape " characters for proper functioning of dunst config reader (for
|
|
## example "#ffeegg").
|
|
##
|
|
## You can define X_res variables in $HOME/.Xresources file. For in depth
|
|
## syntax go to https://wiki.archlinux.org/index.php/X_resources.
|
|
##
|
|
###############################################################################
|
|
|
|
set -e
|
|
|
|
# Check if appres is installed
|
|
if [ ! "$(command -v appres)" ]; then
|
|
printf 'Install xorg-appres in archlinux and x11-utils in debian/ubuntu.\n'
|
|
exit 1
|
|
fi
|
|
|
|
readonly script_name="$(basename "$0")"
|
|
readonly base_dir="$(realpath "$(dirname "$0")")"
|
|
|
|
# Show ussage
|
|
usage() {
|
|
grep -e '^##[^#]*$' "$base_dir/$script_name" | \
|
|
sed -e "s/^##[[:space:]]\{0,1\}//g" \
|
|
-e "s/<script_name>/${script_name}/g"
|
|
exit 2
|
|
} 2>/dev/null
|
|
|
|
# Show help
|
|
if [ "$#" -gt 0 ]; then
|
|
if ! [[ "$1" == "--help" || "$1" == "-h" ]]; then
|
|
printf '\nUnknown option.\n'
|
|
fi
|
|
usage
|
|
fi
|
|
|
|
# Function to get resource values
|
|
xrdb_get () {
|
|
output="$(appres Dunst | grep "$1:" | head -n1 | cut -f2)"
|
|
default="$2"
|
|
printf '%s' "${output:-$default}"
|
|
}
|
|
|
|
#
|
|
# Attributes dictionary. Add or remove attributes (see header for more info)
|
|
#
|
|
declare -A theme_attr_dict=(
|
|
["global-font"]="$(xrdb_get 'font' 'Monospace') $(xrdb_get '*.font_size:' '11')"
|
|
["global-frame_width"]="$(xrdb_get 'border_width' '1')"
|
|
["global-frame_color"]="\"$(xrdb_get 'color8' '#65737e')\""
|
|
|
|
["urgency_low-background"]="\"$(xrdb_get 'color0' '#2b303b')\""
|
|
["urgency_low-foreground"]="\"$(xrdb_get 'color4' '#65737e')\""
|
|
["urgency_low-frame_color"]="\"$(xrdb_get 'color4' '#65737e')\""
|
|
|
|
["urgency_normal-background"]="\"$(xrdb_get 'color0' '#2b303b')\""
|
|
["urgency_normal-foreground"]="\"$(xrdb_get 'color2' '#a3be8c')\""
|
|
["urgency_normal-frame_color"]="\"$(xrdb_get 'color2' '#a3be8c')\""
|
|
|
|
["urgency_critical-background"]="\"$(xrdb_get 'color0' '#2b303b')\""
|
|
["urgency_critical-foreground"]="\"$(xrdb_get 'color1' '#bf616a')\""
|
|
["urgency_critical-frame_color"]="\"$(xrdb_get 'color1' '#bf616a')\""
|
|
)
|
|
|
|
# Attributes dictionary keys.
|
|
readonly valid_keys="${!theme_attr_dict[@]}"
|
|
|
|
#
|
|
# File paths
|
|
#
|
|
# User config dir and file
|
|
readonly user_conf_dir="${XDG_CONFIG_HOME:-$HOME/.config}/dunst"
|
|
readonly user_conf="$user_conf_dir/dunstrc"
|
|
|
|
# Default config dir and example file
|
|
example_conf_dir="/usr/share/dunst"
|
|
example_conf="$example_conf_dir/dunstrc"
|
|
|
|
# User xresources color config file
|
|
readonly user_xr_color_conf="$user_conf_dir/dunstrc_xr_colors"
|
|
|
|
|
|
# Check if the user config directory exists
|
|
if ! [ -d "$user_conf_dir" ]; then
|
|
printf 'Creating folder "%s".\n' "$user_conf_dir"
|
|
mkdir -p "$user_conf_dir"
|
|
fi
|
|
|
|
# Check if the user config file exists
|
|
if ! [ -f "$user_conf" ]; then
|
|
printf '"%s" file does not exist.\nChecking for config file example.' \
|
|
"$user_conf"
|
|
|
|
if [ -d "/usr/share/dunst" ]; then
|
|
# Archlinux default dir and example file
|
|
example_conf_dir="/usr/share/dunst"
|
|
|
|
if [ -f "$example_conf_dir/dunstrc" ]; then
|
|
example_conf="$example_conf_dir/dunstrc"
|
|
else
|
|
printf 'Could not find the example config file in "%s".
|
|
\nPlease, change $example_conf variable in the script.' \
|
|
"$example_conf_dir"
|
|
exit 1
|
|
fi
|
|
|
|
elif [ -d "/usr/share/doc/dunst" ]; then
|
|
# Debian/Ubuntu default dir
|
|
example_conf_dir="/usr/share/doc/dunst"
|
|
|
|
if [ -f "$example_conf_dir/dunstrc.example.gz" ]; then
|
|
# Ubuntu <= 17.10 and Debian <= 1.2.0-2 example file:
|
|
example_conf="$example_conf_dir/dunstrc.example.gz"
|
|
elif [ -f "$example_conf_dir/dunstrc.gz" ]; then
|
|
# Ubuntu >= 18.04 and Debian >= 1.3.0-2 example file:
|
|
example_conf="$example_conf_dir/dunstrc.gz"
|
|
else
|
|
printf 'Could not find the example config file in "%s".
|
|
\nPlease, change $example_conf variable in the script.' \
|
|
"$example_conf_dir"
|
|
exit 1
|
|
fi
|
|
|
|
else
|
|
printf 'Could not find the example config directory.
|
|
\nPlease, change $example_conf_dir variable in the script.'
|
|
exit 1
|
|
fi
|
|
|
|
printf 'Copying example config to "%s".\n' "$user_conf_dir"
|
|
|
|
# Get the extension to check if the file is compressed
|
|
if [[ "${example_conf##*\.}" == "gz" ]]; then
|
|
# Extract example file to user config file
|
|
gunzip -c "$example_conf" > "$user_conf"
|
|
else
|
|
cp "$example_conf" "$user_conf_dir"
|
|
fi
|
|
|
|
fi
|
|
|
|
# Regular expressions
|
|
readonly re_section_line='^\[(.*)\]$'
|
|
readonly re_empty_comment_line='(^$)|(^[[:space:]]*(\#)|(;))'
|
|
readonly re_attribute_line='^([[:space:]]*)([_[:alnum:]]+)'
|
|
|
|
# Create an array with the file lines
|
|
mapfile -t conf < "$user_conf"
|
|
|
|
# Iterate over the file lines
|
|
for idx in "${!conf[@]}"; do
|
|
# Current line
|
|
curr_line="${conf[$idx]}"
|
|
# If we are in a new section:
|
|
if [[ "$curr_line" =~ $re_section_line ]]; then
|
|
curr_section="${BASH_REMATCH[1]}"
|
|
continue
|
|
fi
|
|
# Skip the line if it is empty or has a comment
|
|
if [[ "$curr_line" =~ $re_empty_comment_line ]]; then
|
|
continue
|
|
fi
|
|
# Get the attribute in the current line
|
|
[[ "$curr_line" =~ $re_attribute_line ]]
|
|
curr_attr_name="${BASH_REMATCH[2]}"
|
|
curr_sett_name="${curr_section}-${curr_attr_name}"
|
|
# If the current attribute is not in our dictionary, continue
|
|
case "$valid_keys" in
|
|
*"$curr_sett_name"*)
|
|
printf -v conf[$idx] ' %s = %s' \
|
|
"${curr_attr_name}" \
|
|
"${theme_attr_dict[$curr_sett_name]}"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Create a header for the xr_color config file
|
|
user_xr_color_conf_content="\
|
|
###################################
|
|
#
|
|
# Config file created with
|
|
# $script_name wrapper
|
|
#
|
|
###################################
|
|
|
|
"
|
|
|
|
# After everything is completed, write the new config to a file
|
|
user_xr_color_conf_content+="$(printf '%s\n' "${conf[@]}")"
|
|
|
|
printf '%s\n' "$user_xr_color_conf_content" > "$user_xr_color_conf"
|
|
|
|
printf '"%s" updated successfully.\n' "$user_xr_color_conf"
|
|
|