From b98248fad873d60c4779220a3bca5b0c32b103c4 Mon Sep 17 00:00:00 2001 From: Bernardo Magri Date: Sun, 12 Jul 2026 08:31:31 +0100 Subject: [PATCH] feat(theme): themed monochrome override for the EasyEffects tray icon (#89) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EasyEffects 8 publishes SNI IconName com.github.wwmm.easyeffects, which Papirus renders as its full-colour blue equaliser — the one splash of colour in an otherwise monochrome Waybar tray (nm-applet, udiskie & co resolve to Papirus symbolics). Fix at the shared icon-theme layer so it holds for ALL themes at once: wrap the resolved icon set in a thin child theme, Nomarchy-icons, that Inherits it and ships a palette-coloured monochrome easyeffects glyph (the app's own -symbolic shape, filled with the theme's colour — the same hue as the bar's glyphs, so it tracks every theme/mode on switch). The child becomes the session icon theme; a scalable override out-resolves the parent's fixed-size icon at every requested size, while every other icon still falls through to the parent unchanged. Since iconTheme feeds both stylix (GTK) and rofi, wrapping it once here covers generated and whole-swap themes with no per-theme files. Adding a future offender is one more SVG in scalable/apps. Mechanism validated by GTK IconTheme lookup (override wins at 16/22/24/ 32px; udiskie/nm/folder icons still resolve from Papirus). Icon pkg builds; fill=#D3DAE0, Inherits=Papirus-Dark under Boreal. Co-Authored-By: Claude Fable 5 --- ...ettings.local.json.tmp.230032.cb92e389a1ad | 96 +++++++++++++++++++ modules/home/theme.nix | 65 ++++++++++++- 2 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 .claude/settings.local.json.tmp.230032.cb92e389a1ad diff --git a/.claude/settings.local.json.tmp.230032.cb92e389a1ad b/.claude/settings.local.json.tmp.230032.cb92e389a1ad new file mode 100644 index 0000000..2e333cb --- /dev/null +++ b/.claude/settings.local.json.tmp.230032.cb92e389a1ad @@ -0,0 +1,96 @@ +{ + "permissions": { + "allow": [ + "Read", + "Edit", + "Write", + "Glob", + "Grep", + "Bash(*)", + "Bash(ls *)", + "Bash(cat *)", + "Bash(head *)", + "Bash(tail *)", + "Bash(grep *)", + "Bash(rg *)", + "Bash(find *)", + "Bash(tree *)", + "Bash(wc *)", + "Bash(file *)", + "Bash(stat *)", + "Bash(du *)", + "Bash(df *)", + "Bash(which *)", + "Bash(diff *)", + "Bash(jq *)", + "Bash(sha256sum *)", + "Bash(mkdir *)", + "Bash(cp *)", + "Bash(mv *)", + "Bash(touch *)", + "Bash(ln -s *)", + "Bash(tar *)", + "Bash(nix *)", + "Bash(nix-store *)", + "Bash(nix-instantiate *)", + "Bash(./tools/test-live-iso.sh *)", + "Bash(./tools/test-install.sh *)", + "Bash(./tools/audit-theme-design.py *)", + "Bash(./tools/check-option-docs.py *)", + "Bash(./tools/check-theme-contrast.py *)", + "Bash(./tools/import-palettes.py *)", + "Bash(./tools/vm/qmp.py *)", + "Bash(./tools/vm/vncshot.py *)", + "Bash(./tools/vm/gap-analysis.py *)", + "Bash(python3 tools/*)", + "Bash(bash tools/*)", + "Bash(qemu-system-x86_64 *)", + "Bash(qemu-img *)", + "Bash(git status *)", + "Bash(git diff *)", + "Bash(git log *)", + "Bash(git show *)", + "Bash(git add *)", + "Bash(git commit *)", + "Bash(git branch *)", + "Bash(git switch *)", + "Bash(git checkout *)", + "Bash(git restore *)", + "Bash(git stash *)", + "Bash(git worktree *)", + "Bash(systemctl --user status *)", + "Bash(journalctl --user *)", + "Bash(pgrep *)", + "Bash(pkill -f qemu*)", + "WebFetch(domain:wiki.hyprland.org)", + "WebSearch", + "WebFetch(domain:github.com)", + "WebFetch(domain:wiki.hypr.land)", + "WebFetch(domain:itsfoss.gitlab.io)", + "WebFetch(domain:raw.githubusercontent.com)", + "Bash(cat)", + "Bash(echo \"exit=$?\")", + "Bash(getent hosts *)", + "Bash(git cherry-pick *)", + "Bash(echo \"push-exit=$?\")", + "Bash(nomarchy-pull)", + "Bash(nomarchy-home)", + "Bash(text)" + ], + "deny": [ + "Bash(sudo *)", + "Bash(git push --force *)", + "Bash(git push -f *)" + ], + "ask": [ + "Bash(git push *)", + "Bash(rm *)", + "Bash(git reset --hard *)", + "Bash(git clean *)", + "Bash(nix-collect-garbage *)", + "Bash(curl *)", + "Bash(wget *)" + ], + "defaultMode": "default" + } +} diff --git a/modules/home/theme.nix b/modules/home/theme.nix index a7cd0d4..e163e17 100644 --- a/modules/home/theme.nix +++ b/modules/home/theme.nix @@ -200,10 +200,73 @@ let name = "nomarchy-icon-themes"; paths = [ papirusPkg matchedPack ]; }; + + # ── Tray-icon overrides (BACKLOG #89) ──────────────────────────────── + # Some SNI apps publish an *app* IconName that the icon set renders in + # full colour (EasyEffects 8 → `com.github.wwmm.easyeffects`, Papirus' + # blue equaliser), so the icon clashes with Waybar's monochrome tray. + # We wrap the resolved set in a thin child theme that `Inherits` it and + # ships palette-coloured monochrome overrides for the offenders, then + # make that child the session icon theme: every *other* icon still + # resolves from the parent unchanged (verified — udiskie, nm-applet and + # file-manager icons all fall through). Theme-following: the fill is the + # palette `text` colour — the same hue as the bar's own glyphs — so it + # is regenerated on every switch and works under any theme/mode. A + # scalable override out-resolves the parent's fixed-size icon at every + # requested size. Adding another offender = one more SVG in scalable/apps. + overrideIconTheme = "Nomarchy-icons"; + easyeffectsGlyph = pkgs.writeText "com.github.wwmm.easyeffects.svg" '' + + + + + + + + + + + + ''; + overrideIndex = pkgs.writeText "index.theme" '' + [Icon Theme] + Name=${overrideIconTheme} + Comment=Nomarchy tray-icon overrides + Inherits=${iconTheme},hicolor + Directories=scalable/apps + + [scalable/apps] + Context=Applications + Size=48 + MinSize=8 + MaxSize=512 + Type=Scalable + ''; + overrideIconPkg = pkgs.runCommand "nomarchy-tray-icons" { } '' + apps="$out/share/icons/${overrideIconTheme}/scalable/apps" + mkdir -p "$apps" + cp ${overrideIndex} "$out/share/icons/${overrideIconTheme}/index.theme" + cp ${easyeffectsGlyph} "$apps/com.github.wwmm.easyeffects.svg" + ''; + # Child + parent joined so the session profile carries both; the child's + # index Inherits the parent by name, so lookups start in the child and + # fall through. This becomes the exposed iconTheme/-Package below. + sessionIconThemePackage = pkgs.symlinkJoin { + name = "nomarchy-session-icons"; + paths = [ overrideIconPkg iconThemePackage ]; + }; in { config = { - nomarchy.theme = checked // { inherit iconTheme border iconThemePackage; }; + # Expose the override child as the session icon theme (it Inherits the + # resolved parent, so downstream consumers — stylix GTK, rofi — behave + # identically save for the tray overrides). `iconTheme` here is the + # child name; the parent name lives on in its index's Inherits. + nomarchy.theme = checked // { + border = border; + iconTheme = overrideIconTheme; + iconThemePackage = sessionIconThemePackage; + }; # Feature toggles the menu writes (settings.nightlight.enable, …), exposed # alongside the appearance state. Feature modules mkDefault-read from here