From 084b2a05004e36c9464620c11a73d812b58d2c2e Mon Sep 17 00:00:00 2001 From: Bernardo Magri Date: Sat, 13 Jun 2026 15:52:41 +0100 Subject: [PATCH] feat(theme-sync): persistent switch notification so slow switches read as progress MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "Applying theme — rebuilding…" toast used the default timeout, so it vanished seconds into a multi-minute home-manager switch — leaving the user with no signal and the impression the selection failed. Now it's persistent (timeout 0) and all theme notifications share a synchronous tag, so swaync REPLACES it in place with "Theme applied ✓" (or a critical failure toast that persists) when the rebuild finishes. notify() grew persistent/urgency/summary params. Honest indeterminate feedback — HM exposes no percentage, so no fake progress bar. Verified: py_compile clean; the full apply→switch→notify path runs end to end (dummy NOMARCHY_REBUILD). The in-place replacement is visible only in a real swaync session. Co-Authored-By: Claude Fable 5 --- README.md | 11 +++---- .../nomarchy-theme-sync.py | 32 +++++++++++++++---- todo.md | 14 -------- 3 files changed, 31 insertions(+), 26 deletions(-) delete mode 100644 todo.md diff --git a/README.md b/README.md index d942592..04cb95c 100644 --- a/README.md +++ b/README.md @@ -309,12 +309,11 @@ close · `SUPER+1..9` workspaces · `Print` region screenshot. screen, tuigreet/MOTD text, and the `distroId` question (it changes `DEFAULT_HOSTNAME` and upstream `isNixos` checks — needs a test pass; nixos-* CLI names stay regardless) -- **Theme-switch feedback:** a switch runs `home-manager switch` (seconds - to minutes), and today the only signal is the notify-send toast - ("Applying theme — rebuilding…"). Add a visible progress indicator so a - slow switch never reads as a failed selection — e.g. a spinner/progress - widget from `nomarchy-theme-sync` (it already brackets the rebuild) or a - Waybar/swaync element while the switch runs. +- **Theme-switch feedback:** ✓ the "rebuilding…" notification is now + persistent (timeout 0) and replaced in place by "applied ✓" / failure + via a synchronous tag, so a multi-minute switch never reads as a failed + selection. (An honest indeterminate indicator — HM gives no % — a + literal progress widget would be cosmetic; revisit only if wanted.) - **Icon themes:** add `icon` to `theme-state.json`, have Stylix/GTK and rofi (`show-icons`) consume it, and ensure the chosen icon theme is pulled into the closure per active theme (a dark/light pair, e.g. diff --git a/pkgs/nomarchy-theme-sync/nomarchy-theme-sync.py b/pkgs/nomarchy-theme-sync/nomarchy-theme-sync.py index 7f23141..16c1e54 100644 --- a/pkgs/nomarchy-theme-sync/nomarchy-theme-sync.py +++ b/pkgs/nomarchy-theme-sync/nomarchy-theme-sync.py @@ -59,10 +59,27 @@ def die(msg: str) -> "None": sys.exit(1) -def notify(body: str) -> None: - if shutil.which("notify-send"): - subprocess.run(["notify-send", "-a", "Nomarchy", "Nomarchy", body], - capture_output=True) +# All Nomarchy theme notifications share this synchronous tag, so the +# notification daemon (swaync) REPLACES the previous one in place instead +# of stacking — the "rebuilding…" toast becomes the "applied ✓" toast. +NOTIFY_SYNC_TAG = "nomarchy-theme-sync" + + +def notify(body: str, summary: str = "Nomarchy", *, + persistent: bool = False, urgency: str = "normal") -> None: + """Desktop notification. persistent (timeout 0) keeps it up for the + whole rebuild so a slow switch never reads as a failed selection; + the success/failure call replaces it via the synchronous tag.""" + if shutil.which("notify-send") is None: + return + subprocess.run( + ["notify-send", "-a", "Nomarchy", + "-u", urgency, + "-t", "0" if persistent else "5000", + "-h", f"string:x-canonical-private-synchronous:{NOTIFY_SYNC_TAG}", + summary, body], + capture_output=True, + ) # ─── State management ───────────────────────────────────────────────────── @@ -145,10 +162,13 @@ def run_switch() -> None: return log(f"rebuilding: {' '.join(argv)}") - notify("Applying theme — rebuilding the desktop…") + # Persistent (timeout 0): stays up for the whole rebuild — replaced + # in place by the success/failure notification below — so a multi- + # minute switch never looks like it silently failed. + notify("Applying theme — rebuilding the desktop…", persistent=True) result = subprocess.run(argv) # stream output to the caller's terminal if result.returncode != 0: - notify("Theme rebuild FAILED — see terminal / journal") + notify("Theme rebuild FAILED — see terminal / journal", urgency="critical") die("rebuild failed (state file already updated; fix and re-run)") notify("Theme applied ✓") diff --git a/todo.md b/todo.md deleted file mode 100644 index d71ba82..0000000 --- a/todo.md +++ /dev/null @@ -1,14 +0,0 @@ -# Items to do - -## one item per commit in the repo - -- Let's add some type of progress bar for when the user switch themes? That way we can have a visual feedback instead of the user thinking the selection failed -- Let's add icon themes and make sure each theme selects an icon theme to use (and that the icon theme is pulled for installation) -- Let's install starship or some other tool to make the terminal look nice. We can configure it nicely by default -- We can also add tools and set aliases, for example change cat for bat, grep for ripgrep, etc... -- We can install by default for the user applications to make it a complete desktop workstation, such as vscode, libreoffice, gimp, inkscape, texlivefull. Maybe we should also add a way for the user to "turn off" any of those apps if the user does not want them installed -- Let's tweak the Nomarchy plymouth theme. The logo is too dark and the constrast does not look good with the dark background -- When the machine hibernates the user already needs to type the luks password to resume it. However, the screen gets locked by hyprlock anyway and the user needs to enter the password twice -- Let's have a rofi menu item that shows all the current assigned keybindings -- We can assign SUPER+Space for rofi dmenu and SUPER+m for the main menu. -