aboutsummaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to 'bin')
-rwxr-xr-xbin/udt-accent53
1 files changed, 51 insertions, 2 deletions
diff --git a/bin/udt-accent b/bin/udt-accent
index 2dfc9a0..17a225d 100755
--- a/bin/udt-accent
+++ b/bin/udt-accent
@@ -99,6 +99,11 @@ POWER_ICONS = {
# The sddm user reaches it through the 0711 home, so it has to stay 0644.
AVATAR = Path.home() / ".user-icon.jpg"
+# wallp's config and state: which output each logical screen (H, V) is, and
+# the wallpaper on it. Read so the greeter can show each monitor its own
+# wallpaper, as the desktop does.
+WALLP = Path.home() / ".config" / "wallp"
+
def write_atomic(path, content, mode=None, dir_mode=None):
"""Write a file atomically, so no reader ever sees it half-written.
@@ -502,7 +507,32 @@ def power_icons():
return {key: find_icon(theme, names) for key, names in POWER_ICONS.items()}
-def sddm_conf(palette, name, image, icons=None, avatar=""):
+def screen_wallpapers(conf=WALLP):
+ """Each output's wallpaper, {output: path}, from wallp's conf and state.
+
+ Empty when wallp is not set up; a screen with no saved wallpaper is left
+ out. Either way the greeter falls back to `background` for that screen.
+ """
+ outputs = {}
+ try:
+ for line in (conf / "wallp.conf").read_text().splitlines():
+ key, _, val = line.partition("=")
+ if key in ("OUTPUT_H", "OUTPUT_V") and val:
+ outputs[key[-1]] = val
+ except OSError:
+ return {}
+ walls = {}
+ for side, output in outputs.items():
+ try:
+ path = (conf / f"wall_{side.lower()}").read_text().strip()
+ except OSError:
+ continue
+ if path:
+ walls[output] = os.path.realpath(path)
+ return walls
+
+
+def sddm_conf(palette, name, image, icons=None, avatar="", walls=None):
"""The SDDM theme config, as an INI fragment.
theme.conf.user overrides theme.conf and is exposed to the theme as the
@@ -516,6 +546,9 @@ def sddm_conf(palette, name, image, icons=None, avatar=""):
f"background={os.path.realpath(image)}",
f"accent={ACCENTS[name]}",
]
+ # Per-screen wallpapers, keyed by output name. The greeter prefers these
+ # over `background` on the screen they name.
+ lines += [f"background_{out}={path}" for out, path in (walls or {}).items()]
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]
@@ -539,7 +572,8 @@ def write_sddm(name, image):
file=sys.stderr)
return
write_atomic(SDDM_OUTPUT, sddm_conf(palette, name, image, power_icons(),
- str(AVATAR) if AVATAR.is_file() else ""),
+ str(AVATAR) if AVATAR.is_file() else "",
+ screen_wallpapers()),
mode=0o644, dir_mode=0o755)
@@ -780,6 +814,21 @@ def selftest():
assert "\navatar=/tmp/me.jpg\n" in "\n" + text
assert f"\navatarUser={getpass.getuser()}\n" in "\n" + text
+ # Per-screen wallpapers come from wallp's output names and saved state; a
+ # screen with no saved wallpaper is left out, and no wallp at all gives none.
+ with tempfile.TemporaryDirectory() as tmpdir:
+ conf = Path(tmpdir)
+ assert screen_wallpapers(conf) == {}
+ (conf / "wallp.conf").write_text("# c\nOUTPUT_H=DP-1\nOUTPUT_V=DP-3\nDEFAULT_H=~/x\n")
+ (conf / "wall_h").write_text("/tmp/h.jpg\n")
+ assert screen_wallpapers(conf) == {"DP-1": "/tmp/h.jpg"}
+ (conf / "wall_v").write_text("/tmp/v.png\n")
+ walls = screen_wallpapers(conf)
+ assert walls == {"DP-1": "/tmp/h.jpg", "DP-3": "/tmp/v.png"}, walls
+ text = sddm_conf({}, FALLBACK, "/tmp/h.jpg", walls=walls)
+ assert "\nbackground_DP-1=/tmp/h.jpg\n" in text
+ assert "\nbackground_DP-3=/tmp/v.png\n" in text
+
got = power_icons()
assert set(got) == {"powerIcon", "rebootIcon", "suspendIcon", "hibernateIcon"}