aboutsummaryrefslogtreecommitdiffstats
path: root/bin/udt-accent
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-25 18:43:24 +0200
committerDanilo M. <danix@danix.xyz>2026-09-25 18:43:24 +0200
commit114d0a065c0e6d23a8c47e1b4fa23cbedb56c38e (patch)
tree5df02f3bb02701cb3a2b5aa5f258196a4a4b25ae /bin/udt-accent
parentf0b0e9dbb9062c38b40cb6984be5dbc2ce12948a (diff)
downloadunified-desktop-theme-114d0a065c0e6d23a8c47e1b4fa23cbedb56c38e.tar.gz
unified-desktop-theme-114d0a065c0e6d23a8c47e1b4fa23cbedb56c38e.zip
feat(accent): hand the login avatar to the SDDM theme
The greeter drew the AccountsService icon while hyprlock and the rofi powermenu draw ~/.user-icon.jpg, so one login showed two pictures. udt-accent now writes that path as `avatar`, plus `avatarUser` naming who it belongs to, into the generated theme.conf.user. Both stay empty when the file is missing so the greeter keeps its fallback. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'bin/udt-accent')
-rwxr-xr-xbin/udt-accent22
1 files changed, 20 insertions, 2 deletions
diff --git a/bin/udt-accent b/bin/udt-accent
index c0b6529..e366bb1 100755
--- a/bin/udt-accent
+++ b/bin/udt-accent
@@ -14,6 +14,7 @@ running `wal -i`, because `wal -i` rewrites the whole ~/.cache/wal directory
including the terminal's ANSI colors. See the design spec for why that matters.
"""
+import getpass
import json
import math
import os
@@ -78,6 +79,11 @@ POWER_ICONS = {
"hibernateIcon": ["system-hibernate", "system-suspend-hibernate"],
}
+# The login avatar hyprlock and the rofi powermenu draw, handed to the greeter
+# so the login screen shows the same file instead of the AccountsService icon.
+# The sddm user reaches it through the 0711 home, so it has to stay 0644.
+AVATAR = Path.home() / ".user-icon.jpg"
+
def write_atomic(path, content, mode=None, dir_mode=None):
"""Write a file atomically, so no reader ever sees it half-written.
@@ -408,7 +414,7 @@ def power_icons():
return {key: find_icon(theme, names) for key, names in POWER_ICONS.items()}
-def sddm_conf(palette, name, image, icons=None):
+def sddm_conf(palette, name, image, icons=None, avatar=""):
"""The SDDM theme config, as an INI fragment.
theme.conf.user overrides theme.conf and is exposed to the theme as the
@@ -425,6 +431,10 @@ def sddm_conf(palette, name, image, icons=None):
lines += [f"{key}={palette.get(key, '#000000')}" for key in SDDM_KEYS]
icons = icons or {}
lines += [f"{key}={icons.get(key, '')}" for key in POWER_ICONS]
+ # The avatar belongs to whoever ran udt-accent; the greeter only uses it
+ # when that username is the one being logged in.
+ lines += [f"avatarUser={getpass.getuser() if avatar else ''}",
+ f"avatar={avatar}"]
return "\n".join(lines) + "\n"
@@ -440,7 +450,8 @@ def write_sddm(name, image):
print("udt-accent: palette.rasi unreadable, skipping SDDM theme",
file=sys.stderr)
return
- write_atomic(SDDM_OUTPUT, sddm_conf(palette, name, image, power_icons()),
+ write_atomic(SDDM_OUTPUT, sddm_conf(palette, name, image, power_icons(),
+ str(AVATAR) if AVATAR.is_file() else ""),
mode=0o644, dir_mode=0o755)
@@ -626,6 +637,13 @@ def selftest():
assert f"\n{key}=" in "\n" + text, f"sddm conf missing {key}"
assert "\npowerIcon=/tmp/power.svg" in "\n" + text
+ # No avatar leaves both keys empty so the greeter falls back to
+ # AccountsService; a set one names the user it belongs to.
+ assert "\navatar=\n" in "\n" + text and "\navatarUser=\n" in "\n" + text
+ text = sddm_conf(palette, FALLBACK, str(probe_image), icons, "/tmp/me.jpg")
+ assert "\navatar=/tmp/me.jpg\n" in "\n" + text
+ assert f"\navatarUser={getpass.getuser()}\n" in "\n" + text
+
got = power_icons()
assert set(got) == {"powerIcon", "rebootIcon", "suspendIcon", "hibernateIcon"}