diff options
Diffstat (limited to 'bin')
| -rwxr-xr-x | bin/udt-accent | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/bin/udt-accent b/bin/udt-accent index 391664b..610b04e 100755 --- a/bin/udt-accent +++ b/bin/udt-accent @@ -47,6 +47,18 @@ PALETTE_RASI = Path.home() / ".config" / "rofi" / "udt" / "palette.rasi" # with the rest of the palette and ~/.cache/wal holds nothing but that link. COLORS_JSON = CACHE / "colors.json" +# The SDDM theme's live palette. ~/.cache is 0700 and unreachable to the sddm +# user, ~/.local/share is 0755, so the file has to live here. Root symlinks +# /usr/share/sddm/themes/udt/theme.conf.user to it. See the sddm-theme-udt spec. +LIBEXEC = Path.home() / ".local" / "share" / "udt" +SDDM_OUTPUT = LIBEXEC / "sddm-theme.conf" + +# The keys the theme asks for. The names are the same Catppuccin-compat names +# palette.rasi and udt-palette.qml use, so one palette has one vocabulary. +SDDM_KEYS = ["base", "mantle", "crust", "surface0", "surface1", "surface2", + "text", "subtext0", "subtext1", "overlay0", "overlay1", "overlay2", + "red", "yellow", "green", "teal", "blue", "lavender"] + def write_atomic(path, content): """Write a file atomically, so no reader ever sees it half-written. @@ -286,6 +298,39 @@ def write_sublime(name): write_atomic(SUBLIME, new) +def sddm_conf(palette, name, image): + """The SDDM theme config, as an INI fragment. + + theme.conf.user overrides theme.conf and is exposed to the theme as the + `config` object. It is data parsed by QSettings, never executed, so nothing + the login user can write reaches the greeter as code. + """ + lines = [ + "# Generated by udt-accent. Do not edit.", + "[General]", + "type=image", + f"background={os.path.realpath(image)}", + f"accent={ACCENTS[name]}", + ] + lines += [f"{key}={palette.get(key, '#000000')}" for key in SDDM_KEYS] + return "\n".join(lines) + "\n" + + +def write_sddm(name, image): + """Write the live SDDM palette, atomically, world-readable. + + World-readable because the greeter runs as the sddm user. The atomic writer + creates the file 0600, so the mode is fixed up here. + """ + palette = read_palette() + if not palette: + print("udt-accent: palette.rasi unreadable, skipping SDDM theme", + file=sys.stderr) + return + write_atomic(SDDM_OUTPUT, sddm_conf(palette, name, image)) + os.chmod(SDDM_OUTPUT, 0o644) + + def main(image): try: name = snap(signature_color(image)) @@ -298,6 +343,7 @@ def main(image): write_border(name) write_qml(name) write_sublime(name) + write_sddm(name, image) write_colors_json(name, image) # Hyprland only rereads its config on request, and may not be running. @@ -351,6 +397,18 @@ def selftest(): delta = abs(_hue(ACCENTS[neighbour]) - _hue(ACCENTS[name])) assert min(delta, 2 * math.pi - delta) < math.pi, (name, neighbour) + # The SDDM theme reads this file through a symlink, so it has to carry every + # key the theme asks for, and a second run has to overwrite cleanly rather + # than append. + palette = {k: "#1e2030" for k in SDDM_KEYS} + probe_image = Path(tempfile.mkdtemp()) / "wall.png" + probe_image.write_bytes(b"") + text = sddm_conf(palette, FALLBACK, str(probe_image)) + for key in ["type", "background", "accent", *SDDM_KEYS]: + assert f"\n{key}=" in "\n" + text, f"sddm conf missing {key}" + assert text.count("accent=") == 1 + assert "background=" + str(probe_image) in text + print("selftest OK") |
