From 6bd03747c9fa82d1c08059512f04a6565928365d Mon Sep 17 00:00:00 2001 From: Bernardo Magri Date: Wed, 8 Jul 2026 21:07:10 +0100 Subject: [PATCH] fix(waybar): inhibited notification state reads by shape, not color alone MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Item 28 color-only accessibility sweep. Swept every Waybar status indicator for shape/glyph redundancy: all already carry non-color distinction (updates shows a count + self-hides; vpn/doctor/nightlight/ recording self-gate; battery/idle/muted are glyph-distinct) except the swaync notification module — its `inhibited-*` states reused the normal bells (󰂜/󰂚), so an app-inhibited (suppressed) state was distinguished from a normal one by color alone. Route every suppressed state (DND + inhibited) to the bell-off glyph 󰂛 + @muted, so "notifications are off right now" reads by SHAPE. Applied to the generated bar and all four whole-swaps (summer-day/night use their own bell-off glyph; executive-slate/boreal use 󰂛) — parity rule. Reuses the glyph DND already ships, so no new codepoint / tofu risk. Verified: V0 (flake check --no-build; 4 jsoncs valid JSON) + V1 (built homeConfigurations.nomarchy.activationPackage — the built config has inhibited-* = U+F009B and style.css routes .inhibited-* → @muted). V3 pending: live inhibited-state render with an app holding an inhibitor (HARDWARE-QUEUE). MEMORY gains the "status is never color-only" invariant. Co-Authored-By: Claude Opus 4.8 --- agent/BACKLOG.md | 22 +++++++++++++++------- agent/HARDWARE-QUEUE.md | 9 +++++++++ agent/JOURNAL.md | 24 ++++++++++++++++++++++++ agent/MEMORY.md | 9 +++++++++ modules/home/waybar.nix | 16 +++++++++++----- themes/boreal/waybar.css | 4 +++- themes/boreal/waybar.jsonc | 4 ++-- themes/executive-slate/waybar.css | 4 +++- themes/executive-slate/waybar.jsonc | 4 ++-- themes/summer-day/waybar.jsonc | 4 ++-- themes/summer-night/waybar.jsonc | 4 ++-- 11 files changed, 82 insertions(+), 22 deletions(-) diff --git a/agent/BACKLOG.md b/agent/BACKLOG.md index ed6a6f5..aea893a 100644 --- a/agent/BACKLOG.md +++ b/agent/BACKLOG.md @@ -175,13 +175,21 @@ palettes + visual pass over previews; identity-aware curation):** - **P2 · text-on-surface < 4.5:** ristretto 3.88, latte 4.39 (menus and chips draw text on surface). - **P3 · accentAlt-on-base < 3:** latte 2.34, summer-day 2.83. -- **Design rule (systemic, beats palette surgery): status is never - color-only.** good/warn collapse under protanopia on ~half the - themes and good/bad under deuteranopia (59 pair-findings) — that's - inherent to red/green/yellow, not fixable per-palette. Battery and - recording already carry glyph changes; sweep the remaining - color-only indicators (updates count, notification dot, VPN shield - states) for shape/glyph redundancy. +- ~~**Design rule (systemic): status is never color-only.**~~ ✓ swept + iteration #69 (2026-07-08). good/warn collapse under protanopia and + good/bad under deuteranopia is inherent to red/green/yellow, not + fixable per-palette — but the sweep found every Waybar status + indicator already carries non-color redundancy: **updates** shows a + count (`󰚰 N`) and self-hides; **vpn/doctor/nightlight/recording** + self-gate (presence *is* the state); **battery** changes glyph by + level + bolt-on-charge; **idle_inhibitor** (󰅶/󰾪) and + **pulseaudio.muted** (󰝟) are glyph-distinct. The one real gap: swaync + **inhibited-** states reused the normal bells (󰂜/󰂚), so "notifications + suppressed by an inhibitor" was distinguished from normal by *color + alone* — fixed by routing every suppressed state (DND or inhibited) to + the bell-off glyph + @muted, in the generated bar and all four + whole-swaps (parity). V3-pending: confirm the muted bell-off renders + while an app holds a notification inhibitor (HARDWARE-QUEUE). - **Identity exemptions, made explicit:** vantablack + white (deliberately hueless statuses), lumon (all-blue), hackerman (matrix green statuses), matte-black/retro-82 (off-family hues) are diff --git a/agent/HARDWARE-QUEUE.md b/agent/HARDWARE-QUEUE.md index 85a4008..36aef53 100644 --- a/agent/HARDWARE-QUEUE.md +++ b/agent/HARDWARE-QUEUE.md @@ -15,6 +15,15 @@ QA machine), the **T14s** (webcam case). - [ ] **SSH_AUTH_SOCK for GUI clients** — after relogin, launch a GUI git client (or `rofi`-launched terminal-less app) and confirm it reaches gpg-agent's SSH socket without an interactive shell parent. +- [ ] **Notification inhibited-state glyph** (item 28 color-only sweep, + iteration #69) — have an app hold a notification inhibitor (e.g. run + a fullscreen video, or `busctl --user call org.freedesktop.Notifications + … Inhibit`); the Waybar bell must switch to the muted **bell-off** 󰂛 + (same glyph as DND), NOT the normal bell 󰂜/󰂚. Then release it → the + bell returns. Repeat on a whole-swap bar (summer-day/night use their + own bell-off glyph, executive-slate/boreal use 󰂛). The glyph itself + already renders (DND uses it); this only confirms swaync emits the + `inhibited-*` class and the bar routes it. - [x] **Night-light full cycle** — first menu enable rebuilds + hyprsunset starts; later toggles are instant (no rebuild); an *off* survives reboot (ExecCondition); stopping hyprsunset restores gamma. diff --git a/agent/JOURNAL.md b/agent/JOURNAL.md index 511714b..ba21fc8 100644 --- a/agent/JOURNAL.md +++ b/agent/JOURNAL.md @@ -17,6 +17,30 @@ Template: --- +## 2026-07-08 — Color-only status sweep + inhibited-bell fix (iteration #69) +- **Task:** BACKLOG #28 slice — the audit's systemic "status is never + color-only" finding (accessibility): sweep the remaining Waybar status + indicators for shape/glyph redundancy. +- **Did:** swept every status module. All already carry non-color + redundancy (updates shows a count + self-hides; vpn/doctor/nightlight/ + recording self-gate; battery/idle/muted are glyph-distinct) EXCEPT one: + swaync `inhibited-*` reused the normal bells (󰂜/󰂚), so an inhibitor + suppressing notifications was distinguished from normal by *color alone*. + Fixed: route every suppressed state (DND + inhibited) to the bell-off + glyph 󰂛 + @muted — generated bar (waybar.nix) AND all four whole-swaps + (summer-day/night use their own bell-off, executive-slate/boreal 󰂛; + parity rule). Reused the proven DND glyph → zero tofu risk. +- **Verified:** V0 (flake check --no-build green; all 4 jsoncs valid JSON). + V1: built homeConfigurations.nomarchy.activationPackage; confirmed in the + *built* artifact that inhibited-none/notification = U+F009B (bell-off, + was F009C/F009A) and style.css routes .inhibited-* → @muted. +- **Pending:** V3 queued (HARDWARE-QUEUE, Any-machine) — confirm the muted + bell-off renders while an app holds a notification inhibitor. Low risk: + the glyph already ships for DND. MEMORY gains the "status is never + color-only" design invariant (regression guard). +- **Next suggestion:** #28 remaining is [human] (icon-weight call) or + V3-visual; likely a QA sweep or await Bernardo on #29/#33. + ## 2026-07-08 — Migration guide: existing NixOS → Nomarchy (docs, direct request) - **Task:** Bernardo asked whether THIS machine (TuringMachine, NixOS 25.11) can migrate to Nomarchy without a reinstall, keeping all files — and to diff --git a/agent/MEMORY.md b/agent/MEMORY.md index b46858f..b533d53 100644 --- a/agent/MEMORY.md +++ b/agent/MEMORY.md @@ -62,6 +62,15 @@ iteration would otherwise rediscover. state write re-copies the source before eval — the wallpapers-artifact split (BACKLOG LATER) is the decided fix (§ Faster switches). +## Design invariants +- **Waybar status is never color-only** (item 28 sweep, iteration #69): + every status module must distinguish its states by SHAPE (glyph) or + presence (self-hide), never color alone — good/warn/bad collapse under + color-blindness. When adding a state, give it a distinct glyph or gate + the module on it; a new `class` that only recolors an existing glyph is + a regression. Suppressed notification states (DND *and* app-inhibited) + all use the bell-off glyph + @muted. + ## Gotchas (cost a debugging session once) - Waybar `layer: top` renders above **even real-fullscreen windows** — the bar draws over a fullscreen video. `layer: bottom` lets the fullscreen diff --git a/modules/home/waybar.nix b/modules/home/waybar.nix index fd4a61b..3d8efb2 100644 --- a/modules/home/waybar.nix +++ b/modules/home/waybar.nix @@ -291,7 +291,10 @@ let # swaync notification bell + Do-Not-Disturb state. `-swb` streams JSON # (text/tooltip/class) on every change, so it tracks count and DND with # no polling. Left-click toggles the panel; right-click toggles DND. - # The `dnd-*` classes (bell-off glyph) are styled muted below. + # Every *suppressed* state — DND or app-inhibited — maps to the bell-off + # glyph 󰂛 and the muted color below, so "notifications are off right now" + # reads by SHAPE, not color alone (color-blind sweep, item 28): inhibited + # used to reuse the normal 󰂜/󰂚 bells, distinguishable only by color. "custom/notification" = { exec = "swaync-client -swb"; return-type = "json"; @@ -302,8 +305,8 @@ let notification = "󰂚"; dnd-none = "󰂛"; dnd-notification = "󰂛"; - inhibited-none = "󰂜"; - inhibited-notification = "󰂚"; + inhibited-none = "󰂛"; + inhibited-notification = "󰂛"; dnd-inhibited-none = "󰂛"; dnd-inhibited-notification = "󰂛"; }; @@ -405,10 +408,13 @@ let size them up a touch more so they read at a glance. */ #custom-powerprofile, #idle_inhibitor { font-size: ${toString (t.fonts.size + 3)}pt; } - /* notifications waiting → accent; Do-Not-Disturb → muted bell-off */ + /* notifications waiting → accent; suppressed (DND or app-inhibited) → + muted bell-off, so it reads by shape+color, never color alone. */ #custom-notification.notification { color: @accent; } #custom-notification.dnd-none, - #custom-notification.dnd-notification { color: @muted; } + #custom-notification.dnd-notification, + #custom-notification.inhibited-none, + #custom-notification.inhibited-notification { color: @muted; } #pulseaudio.muted { color: @muted; } #battery.warning { color: @warn; } diff --git a/themes/boreal/waybar.css b/themes/boreal/waybar.css index dccf0aa..2076eb7 100644 --- a/themes/boreal/waybar.css +++ b/themes/boreal/waybar.css @@ -145,7 +145,9 @@ window#waybar { #custom-notification.notification { color: @accent; } #custom-notification.dnd-none, -#custom-notification.dnd-notification { color: @muted; } +#custom-notification.dnd-notification, +#custom-notification.inhibited-none, +#custom-notification.inhibited-notification { color: @muted; } /* Tray shares the pill's glass — same transparent background, its own modest padding so nm-applet & friends breathe with the status icons. */ diff --git a/themes/boreal/waybar.jsonc b/themes/boreal/waybar.jsonc index 2c8e8f4..4cc3195 100644 --- a/themes/boreal/waybar.jsonc +++ b/themes/boreal/waybar.jsonc @@ -163,8 +163,8 @@ "notification": "󰂚", "dnd-none": "󰂛", "dnd-notification": "󰂛", - "inhibited-none": "󰂜", - "inhibited-notification": "󰂚", + "inhibited-none": "󰂛", + "inhibited-notification": "󰂛", "dnd-inhibited-none": "󰂛", "dnd-inhibited-notification": "󰂛" } diff --git a/themes/executive-slate/waybar.css b/themes/executive-slate/waybar.css index 582e1de..52ba94c 100644 --- a/themes/executive-slate/waybar.css +++ b/themes/executive-slate/waybar.css @@ -159,7 +159,9 @@ window#waybar { #custom-notification.notification { color: @accent; } #custom-notification.dnd-none, -#custom-notification.dnd-notification { color: @muted; } +#custom-notification.dnd-notification, +#custom-notification.inhibited-none, +#custom-notification.inhibited-notification { color: @muted; } #tray { color: @text; } diff --git a/themes/executive-slate/waybar.jsonc b/themes/executive-slate/waybar.jsonc index 00cb66b..f7acfe9 100644 --- a/themes/executive-slate/waybar.jsonc +++ b/themes/executive-slate/waybar.jsonc @@ -159,8 +159,8 @@ "notification": "󰂚", "dnd-none": "󰂛", "dnd-notification": "󰂛", - "inhibited-none": "󰂜", - "inhibited-notification": "󰂚", + "inhibited-none": "󰂛", + "inhibited-notification": "󰂛", "dnd-inhibited-none": "󰂛", "dnd-inhibited-notification": "󰂛" } diff --git a/themes/summer-day/waybar.jsonc b/themes/summer-day/waybar.jsonc index a9f6d1d..241414b 100644 --- a/themes/summer-day/waybar.jsonc +++ b/themes/summer-day/waybar.jsonc @@ -145,8 +145,8 @@ "notification": "", "dnd-none": "", "dnd-notification": "", - "inhibited-none": "", - "inhibited-notification": "", + "inhibited-none": "", + "inhibited-notification": "", "dnd-inhibited-none": "", "dnd-inhibited-notification": "" } diff --git a/themes/summer-night/waybar.jsonc b/themes/summer-night/waybar.jsonc index 9ff5fdf..78c3b32 100644 --- a/themes/summer-night/waybar.jsonc +++ b/themes/summer-night/waybar.jsonc @@ -144,8 +144,8 @@ "notification": "", "dnd-none": "", "dnd-notification": "", - "inhibited-none": "", - "inhibited-notification": "", + "inhibited-none": "", + "inhibited-notification": "", "dnd-inhibited-none": "", "dnd-inhibited-notification": "" }