diff options
Diffstat (limited to 'bin')
| -rwxr-xr-x | bin/udt-accent | 72 | ||||
| -rwxr-xr-x | bin/udt-palette | 18 |
2 files changed, 68 insertions, 22 deletions
diff --git a/bin/udt-accent b/bin/udt-accent index d758ea6..69698d1 100755 --- a/bin/udt-accent +++ b/bin/udt-accent @@ -47,6 +47,12 @@ HYPRLOCK_BORDER_OUTPUT = CACHE / "hyprlock-border.conf" SUBLIME = (Path.home() / ".config" / "sublime-text" / "Packages" / "User" / "udt.sublime-color-scheme") QML_OUTPUT = CACHE / "udt-palette.qml" +# Generated by udt-palette with the scheme's accent and rewritten here with the +# wallpaper's. Both already go stale on a wallpaper change, GRUB's background +# and homepage's staged wallpaper, so following the accent costs no extra step. +REPO = Path(__file__).resolve().parent.parent +GRUB_THEME = REPO.parent / "grub-theme-udt" / "theme.txt" +HOMEPAGE_CSS = REPO / "templates" / "homepage" / "custom.css" # The installed rofi palette, itself generated by udt-palette. Read rather than # duplicated so the QML singleton carries exactly the colours rofi uses, under @@ -381,27 +387,42 @@ def write_colors_json(name, image): subprocess.run(["pywalfox", "update"], capture_output=True, check=False) +def rewrite(path, pattern, value): + """Replace group 1's tail in the first line matching pattern with value. + + For generated files whose accent is replaced by matching the line that + carries it, not a placeholder, so a second run rewrites the first run's + accent. A missing file is not an error: its consumer may not be here. + """ + try: + text = path.read_text() + except FileNotFoundError: + return + new, count = re.subn(pattern, lambda m: m.group(1) + value, text, + count=1, flags=re.M) + if count and new != text: + write_atomic(path, new, mode=path.stat().st_mode & 0o777) + + def write_sublime(name): """Substitute the accent into the Sublime colour scheme install.sh copied. In place: Sublime colour schemes do not cascade, so the accent cannot arrive as a second file. Sublime watches Packages/User and reloads a - scheme when its file changes, so no signal is needed. A missing file is not - an error, Sublime simply may not be installed here. - - This reads the installed copy and has nowhere to recover @ACCENT@ from - once substituted, so the previous accent is replaced by matching the - variable line rather than a placeholder. + scheme when its file changes, so no signal is needed. """ - try: - text = SUBLIME.read_text() - except FileNotFoundError: - return + rewrite(SUBLIME, r'("accent":\s*")[^"]*', ACCENTS[name]) - new, count = re.subn(r'("accent":\s*)"[^"]*"', - lambda m: f'{m.group(1)}"{ACCENTS[name]}"', text, count=1) - if count and new != text: - write_atomic(SUBLIME, new) + +def write_grub(name): + """The accent on theme.txt's '# udt:' line, which GRUB's build reads.""" + rewrite(GRUB_THEME, r"^(# udt: .*\baccent=)#[0-9a-fA-F]{6}", ACCENTS[name]) + + +def write_homepage(name): + """The --udt-accent triple every accent in homepage's custom.css reads.""" + r, g, b = bytes.fromhex(ACCENTS[name].lstrip("#")) + rewrite(HOMEPAGE_CSS, r"^(\s*--udt-accent:\s*)[^;]*", f"{r} {g} {b}") def icon_theme(): @@ -520,6 +541,9 @@ def main(image): write_sublime(name) write_sddm(name, image) write_colors_json(name, image) + # Before the helpers below start, which build and stage these two. + write_grub(name) + write_homepage(name) # Hyprland only rereads its config on request, and may not be running. subprocess.run(["hyprctl", "reload"], capture_output=True, check=False) @@ -565,6 +589,26 @@ def selftest(): assert '"#f5a97f"' not in second and '"#8bd5ca"' in second assert third == second, "accent substitution is not idempotent" + # GRUB and homepage go through the same match-the-line rewrite, so the + # same twice-over test: the scheme's accent first, then the last run's. + with tempfile.TemporaryDirectory() as tmpdir: + f = Path(tmpdir) / "f" + cases = [ + (write_grub, "# udt: bg_alt=#1e2030 accent=#b7bdf8\nx = \"#b7bdf8\"\n", + lambda h: f"# udt: bg_alt=#1e2030 accent={h}\nx = \"#b7bdf8\"\n"), + (write_homepage, ".t {\n --udt-accent: 183 189 248;\n}\n", + lambda h: ".t {\n --udt-accent: %d %d %d;\n}\n" + % tuple(bytes.fromhex(h[1:]))), + ] + for write, start, want in cases: + globals()["GRUB_THEME"] = globals()["HOMEPAGE_CSS"] = f + f.write_text(start) + f.chmod(0o644) + for name in list(ACCENTS)[:2]: + write(name) + assert f.read_text() == want(ACCENTS[name]), f.read_text() + assert f.stat().st_mode & 0o777 == 0o644, "rewrite lost the mode" + # A near-grey has an unstable hue angle and must take the fallback. assert snap("#888888") == FALLBACK, snap("#888888") diff --git a/bin/udt-palette b/bin/udt-palette index cdeb571..86c53d6 100755 --- a/bin/udt-palette +++ b/bin/udt-palette @@ -592,7 +592,6 @@ def gen_homepage(res, scheme, palette): sr, sg, sb, _ = res["surface"] ar, ag, ab, _ = res["surface_alt"] br, bg_, bb, _ = res["bg"] - accent = hex6(res["accent"]) return f"""/* {BANNER.format(scheme=scheme)} * @@ -603,7 +602,10 @@ def gen_homepage(res, scheme, palette): .theme-gray {{ {rows} - --color-logo-start: {triple('accent')}; + /* The scheme's accent until udt-accent rewrites this line with the + * wallpaper's. Every accent below reads it, so that is one line to match. */ + --udt-accent: {triple('accent')}; + --color-logo-start: var(--udt-accent); --color-logo-stop: {triple('info')}; }} @@ -622,10 +624,9 @@ def gen_homepage(res, scheme, palette): background-color: rgb({br} {bg_} {bb} / 50%); }} -/* Accent on secondary labels. Fixed, not wallpaper-tracking: this runs on a - * server with no wallpaper to read. */ +/* Accent on secondary labels. */ .theme-gray .text-theme-500 {{ - color: {accent}; + color: rgb(var(--udt-accent)); }} """ @@ -693,9 +694,10 @@ def gen_conky(res, scheme, palette, template): def gen_grub(res, scheme, palette, template): """GRUB: substitute into the theme template in the grub-theme-udt repo. - theme.txt has no include, so the colours are baked in. The accent is the - scheme's fixed one: nothing at boot can read the wallpaper. The PNG slices - that carry colour are drawn by that repo's build script from this output. + theme.txt has no include, so the colours are baked in. The accent lands only + on the '# udt:' line, where the build script reads it to draw the PNG + slices that carry colour. udt-accent rewrites it there with the wallpaper's, + which is no less stale than the background snapshot the build already takes. """ out = template.replace("@SCHEME@", scheme) for role in ("bg", "bg_alt", "bg_deep", "surface", "fg", "fg_dim", |
