forked from dunst-project/dunst
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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: dunst-project#357
- Loading branch information
Showing
1 changed file
with
255 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 depht | ||
## 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" | ||
|