diff options
| author | Danilo M. <danix@danix.xyz> | 2026-10-07 09:48:15 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-10-07 09:48:15 +0200 |
| commit | 205633a064a560c84989d50cb92237d9173e4d6a (patch) | |
| tree | 157de2c3b024d0559c3b4a04d5fc4af84d508ecb /bin/udt-accent | |
| parent | 2d6bc39e822bd691e1393f7ae8af7098b56d658d (diff) | |
| download | unified-desktop-theme-205633a064a560c84989d50cb92237d9173e4d6a.tar.gz unified-desktop-theme-205633a064a560c84989d50cb92237d9173e4d6a.zip | |
feat(accent): hand SDDM each screen's wallpaper
Write background_<output>= into the SDDM theme config for every screen
wallp manages, read from wallp.conf's OUTPUT_H/OUTPUT_V and the saved
wall_h/wall_v. The greeter shows each monitor its own wallpaper instead
of the horizontal one on both. Missing wallp state writes no keys, so
the greeter falls back to the shared background.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'bin/udt-accent')
| -rwxr-xr-x | bin/udt-accent | 53 |
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"} |
