diff options
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"} |
