diff options
Diffstat (limited to 'bin/udt-accent')
| -rwxr-xr-x | bin/udt-accent | 46 |
1 files changed, 42 insertions, 4 deletions
diff --git a/bin/udt-accent b/bin/udt-accent index 1388db1..ebbac91 100755 --- a/bin/udt-accent +++ b/bin/udt-accent @@ -54,6 +54,13 @@ QML_OUTPUT = CACHE / "udt-palette.qml" REPO = Path(__file__).resolve().parent.parent GRUB_THEME = REPO.parent / "grub-theme-udt" / "theme.txt" HOMEPAGE_CSS = REPO / "templates" / "homepage" / "custom.css" +# conky's heading role is the scheme accent in every scheme, so it follows the +# wallpaper's. highlight (titles' icons, bars, the moon) left on the scheme's +# own hue kept the dashboard that hue whatever the wallpaper, so it takes the +# accent's next hue on the wheel, the border's leading neighbour: related to +# the heading, still told apart from it. color1 is heading and color5 +# highlight in conky.conf.in. +CONKY_CONF = REPO.parent / "conky-theme-udt" / "conky.conf" # The installed rofi palette, itself generated by udt-palette. Read rather than # duplicated so the QML singleton carries exactly the colours rofi uses, under @@ -429,12 +436,15 @@ def write_firefox(image): print(f"udt-accent: firefox new tab not updated: {exc}", file=sys.stderr) -def rewrite(path, pattern, value): +def rewrite(path, pattern, value, in_place=False): """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. + + `in_place` keeps the inode, for a reader that watches the file itself + rather than its directory: an atomic rename would silently end the watch. """ try: text = path.read_text() @@ -443,7 +453,10 @@ def rewrite(path, pattern, value): 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) + if in_place: + path.write_text(new) + else: + write_atomic(path, new, mode=path.stat().st_mode & 0o777) def write_sublime(name): @@ -467,6 +480,21 @@ def write_homepage(name): rewrite(HOMEPAGE_CSS, r"^(\s*--udt-accent:\s*)[^;]*", f"{r} {g} {b}") +def write_conky(name): + """The accent on conky.conf's color1 line (heading), its next hue on color5 + (highlight). + + In place: conky watches the config's inode with inotify and reloads on a + write, so no restart is needed, but a rename would end the watch. A torn + read is not a risk in practice, since conky acts on the event at its next + update, long after this small write has finished. + """ + after = hue_neighbours(name)[1] + for slot, hexval in (("color1", ACCENTS[name]), ("color5", ACCENTS[after])): + rewrite(CONKY_CONF, rf"^(\s*{slot}\s*=\s*')#[0-9a-fA-F]{{6}}", + hexval, in_place=True) + + def icon_theme(): """The icon theme the appearance drawer selected, or "" if unreadable. @@ -616,6 +644,7 @@ def main(image): # Before the helpers below start, which build and stage these two. write_grub(name) write_homepage(name) + write_conky(name) # Hyprland only rereads its config on request, and may not be running. subprocess.run(["hyprctl", "reload"], capture_output=True, check=False) @@ -664,8 +693,8 @@ 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. + # GRUB, homepage and conky 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 = [ @@ -674,15 +703,24 @@ def selftest(): (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:]))), + (write_conky, + " color1 = '#cc0dbf',\n color4 = '#37daea',\n color5 = '#ef60d9',\n", + lambda h: f" color1 = '{h}',\n color4 = '#37daea',\n color5 = " + f"'{ACCENTS[hue_neighbours(HEX_NAME[h])[1]]}',\n"), ] + HEX_NAME = {v: k for k, v in ACCENTS.items()} for write, start, want in cases: globals()["GRUB_THEME"] = globals()["HOMEPAGE_CSS"] = f + globals()["CONKY_CONF"] = f f.write_text(start) f.chmod(0o644) + inode = f.stat().st_ino 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" + if write is write_conky: + assert f.stat().st_ino == inode, "conky rewrite replaced the inode" # A near-grey has an unstable hue angle and must take the fallback. assert snap("#888888") == FALLBACK, snap("#888888") |
