aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-11 10:36:32 +0200
committerDanilo M. <danix@danix.xyz>2026-09-11 10:36:32 +0200
commitdec6a74d4c147ce29b99b49052044642566cedd0 (patch)
treec5f93d6caf2a1b405ceef3d46aec20d32a0ab520
parentf04a1f1dae245e9025344955dbc7e2d18339150b (diff)
downloadunified-desktop-theme-dec6a74d4c147ce29b99b49052044642566cedd0.tar.gz
unified-desktop-theme-dec6a74d4c147ce29b99b49052044642566cedd0.zip
feat: theme dunst in Macchiato with a wallpaper-driven accent frame
Notifications previously drew their colours from the pywal preset, so they were pure black on white and did not match anything else. Structural colours are now fixed Macchiato, with the accent as the frame on normal urgency, a muted surface frame on low, and Macchiato red on critical. Font moves to Noto Sans to match the rest of the desktop. udt-accent substitutes the accent after pywal renders the template, then restarts dunst so it rereads the file. It restarts rather than just killing: nothing else respawns dunst, and a dead dunst means no notifications at all. Also fixes a dangling reference: the template pointed dunst's dmenu at darknix/main.rasi, a theme that no longer exists. The template is tracked here as templates/dunstrc; the live copy is ~/.config/wal/templates/dunstrc. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
-rwxr-xr-xbin/udt-accent34
-rw-r--r--templates/dunstrc75
2 files changed, 109 insertions, 0 deletions
diff --git a/bin/udt-accent b/bin/udt-accent
index fbd6a65..978f340 100755
--- a/bin/udt-accent
+++ b/bin/udt-accent
@@ -39,6 +39,7 @@ MIN_CHROMA = 10.0
OUTPUT = Path.home() / ".cache" / "wal" / "udt-accent.rasi"
BORDER_OUTPUT = Path.home() / ".cache" / "wal" / "udt-border.lua"
+DUNSTRC = Path.home() / ".cache" / "wal" / "dunstrc"
def _to_lab(hexval):
@@ -162,6 +163,38 @@ def write_border(name):
raise
+def write_dunst(name):
+ """Substitute the accent into the dunst config pywal just rendered.
+
+ pywal owns that file, so this runs after it and rewrites in place. A
+ missing file is not an error: dunst simply may not be configured here.
+ """
+ try:
+ text = DUNSTRC.read_text()
+ except FileNotFoundError:
+ return
+
+ if "@ACCENT@" not in text:
+ return
+
+ fd, tmp = tempfile.mkstemp(dir=str(DUNSTRC.parent), suffix=".tmp")
+ try:
+ with os.fdopen(fd, "w") as handle:
+ handle.write(text.replace("@ACCENT@", ACCENTS[name]))
+ os.replace(tmp, DUNSTRC)
+ except BaseException:
+ if os.path.exists(tmp):
+ os.unlink(tmp)
+ raise
+
+ # Restart dunst so it rereads the file. It must be started again, not just
+ # killed: nothing else respawns it, and a dead dunst means no notifications
+ # at all.
+ if subprocess.run(["pkill", "-x", "dunst"], capture_output=True).returncode == 0:
+ subprocess.Popen(["dunst"], start_new_session=True,
+ stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
+
+
def main(image):
try:
name = snap(signature_color(image))
@@ -172,6 +205,7 @@ def main(image):
write_accent(name)
write_border(name)
+ write_dunst(name)
# Hyprland only rereads its config on request, and may not be running.
subprocess.run(["hyprctl", "reload"], capture_output=True, check=False)
diff --git a/templates/dunstrc b/templates/dunstrc
new file mode 100644
index 0000000..44ed700
--- /dev/null
+++ b/templates/dunstrc
@@ -0,0 +1,75 @@
+# See dunst(5) for all configuration options
+[global]
+ monitor = 1
+ follow = none
+ width = 300
+ height = (0, 300)
+ origin = top-right
+ offset = (10, 50)
+ scale = 0
+ notification_limit = 0
+ progress_bar = true
+ progress_bar_height = 10
+ progress_bar_frame_width = 1
+ progress_bar_min_width = 150
+ progress_bar_max_width = 300
+ indicate_hidden = yes
+ transparency = 15
+ separator_height = 2
+ padding = 8
+ horizontal_padding = 8
+ text_icon_padding = 0
+ frame_width = 3
+ frame_color = "@ACCENT@"
+ gap_size = 0
+ separator_color = frame
+ sort = yes
+ font = Noto Sans 11
+ line_height = 0
+ markup = full
+ format = "<b>%a</b>\n<i>%s</i>%p %n\n%b"
+ alignment = left
+ vertical_alignment = center
+ show_age_threshold = 60
+ ellipsize = middle
+ ignore_newline = no
+ stack_duplicates = true
+ hide_duplicate_count = false
+ show_indicators = yes
+ enable_recursive_icon_lookup = true
+ icon_theme = MB-Blueberry-Suru-GLOW
+ icon_position = left
+ icon_corner_radius = 5
+ min_icon_size = 32
+ max_icon_size = 128
+ icon_path = ~/.local/share/icons/MB-Blueberry-Suru-GLOW/status/48/:/usr/share/icons/MB-Blueberry-Suru-GLOW/devices/48/
+ sticky_history = yes
+ history_length = 20
+ dmenu = /usr/bin/rofi -theme ~/.config/rofi/udt/list.rasi -dmenu -p dunst
+ browser = /usr/bin/xdg-open
+ always_run_script = true
+ title = Dunst
+ class = Dunst
+ corner_radius = 10
+ ignore_dbusclose = false
+ mouse_left_click = context, close_current
+ mouse_middle_click = do_action, close_current
+ mouse_right_click = close_all
+# to have a consistent behaviour across releases.
+[experimental]
+ per_monitor_dpi = false
+[urgency_low]
+ background = "#1e2030"
+ foreground = "#a5adcb"
+ frame_color = "#494d64"
+ timeout = 10
+[urgency_normal]
+ background = "#24273a"
+ foreground = "#cad3f5"
+ frame_color = "@ACCENT@"
+ timeout = 10
+[urgency_critical]
+ background = "#24273a"
+ foreground = "#cad3f5"
+ frame_color = "#ed8796"
+ timeout = 0