Browse Source
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: #357master

1 changed files with 255 additions and 0 deletions
@ -0,0 +1,255 @@
|
||||
#!/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" |
||||
|
Loading…
Reference in new issue