quickshell: match mono icons by name, iconPath returns a URI

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
rope 2026-08-21 16:47:36 +01:00
parent d6dd93ea5a
commit 7c89ab366d

View file

@ -19,6 +19,33 @@ let
defaultWall = config.fred.theming.defaultWall;
themeApply = config.fred.theming.apply;
monoIcons = config.fred.theming.monoIcons;
# The set of app icons YAMIS actually ships, as a QML singleton.
#
# AppIcon needs to know whether a given icon came from the monochrome set
# (safe to flatten to one colour) or fell through to Papirus (not — see the
# component). It cannot tell from the resolved source: Quickshell.iconPath
# returns an "image://icon/<name>" provider URI, never a filesystem path,
# so there is no store path or theme directory in it to match on. The name
# is all we get, so the name is what we test.
#
# Built here rather than listed at eval time: reading the icon tree during
# evaluation would mean IFD, and hosts evaluate this straight from the
# Forgejo remote.
monoIconNames = pkgs.runCommand "MonoIcons.qml" { } ''
{
echo "pragma Singleton"
echo "import QtQuick"
echo "QtObject {"
printf ' readonly property var names: ['
for f in ${monoIcons}/apps/16/*.svg ${monoIcons}/apps/scalable/*.svg; do
[ -e "$f" ] || continue
basename "$f" .svg
done | sort -u | while read -r n; do printf '"%s",' "$n"; done
printf ']\n'
echo "}"
} > $out
'';
in
{
config = lib.mkIf (lib.elem config.networking.hostName [ "FredOS-Gaming" "FredOS-Macbook" ]) {
@ -386,11 +413,17 @@ in
channels = mono
'';
in {
"quickshell/MonoIcons.qml" = {
onChange = qsRestart;
source = monoIconNames;
};
"quickshell/qmldir" = {
onChange = qsRestart;
text = ''
singleton Theme 1.0 Theme.qml
singleton Commands 1.0 Commands.qml
singleton MonoIcons 1.0 MonoIcons.qml
Bar 1.0 Bar.qml
Lock 1.0 Lock.qml
Cheatsheet 1.0 Cheatsheet.qml
@ -1318,13 +1351,6 @@ in
readonly property string wxFetch: "${wxFetchScript}"
readonly property string xdgOpen: "${pkgs.xdg-utils}/bin/xdg-open"
readonly property string themeApply: "${themeApply}"
// Directory name of the monochrome icon theme. AppIcon tests
// a resolved icon path against this to decide whether it may
// be tinted see the component for why that is not blanket.
// A name, not the store path: lookups resolve through the
// /run/current-system/sw symlink farm, whose paths never
// contain the store prefix.
readonly property string monoIconDir: "/${baseNameOf monoIcons}/"
}
'';
};
@ -1764,8 +1790,17 @@ in
id: _ai
property string path: ""
property int size: 32
readonly property bool mono:
_ai.path !== "" && _ai.path.indexOf(Commands.monoIconDir) !== -1
// iconPath hands back "image://icon/<name>", so the name
// is the only thing to go on MonoIcons lists what YAMIS
// ships. Anything else (a real file path, a notification
// carrying its own image) is not ours to recolour.
readonly property bool mono: {
if (_ai.path.indexOf("image://icon/") !== 0) return false;
var n = _ai.path.substring(13);
var q = n.indexOf("?");
if (q !== -1) n = n.substring(0, q);
return MonoIcons.names.indexOf(n) !== -1;
}
width: size
height: size