fix: real-hardware QA sweep — wifi, fonts, firmware, Hyprland 0.55, offline switching

Roadmap items 1+2 plus the issues found testing on a Latitude 5410:

- Ship the 10 most popular Nerd Fonts by default (iosevka swapped for
  mononoki: 1.1 GB vs 27 MB) and warn from nomarchy-theme-sync when a
  configured fonts.mono/fonts.ui family isn't installed (fc-match) —
  fontconfig substitutes silently otherwise.
- hardware.enableRedistributableFirmware: installed systems shipped NO
  firmware blobs (wifi/SOF audio/BT) — nixos-generate-config only emits
  microcode lines referencing this flag, it never sets it.
- Live ISO wifi: networking.wireless.enable = mkForce false killed
  NetworkManager's supplicant — since 26.05 the NM module drives its
  wifi backend THROUGH networking.wireless (dbusControlled). Devices
  vanished from nmtui with iwlwifi loaded and no rfkill block.
- Hyprland 0.55: launch sessions via start-hyprland (watchdog; bare
  binary warns), add the new gesture keyword (workspace_swipe is gone —
  touchpads had no gestures at all), media keys via wpctl/bindel/bindl
  plus the missing mic/play/next/prev binds.
- Offline theme switching: pin mustache-go + stdenv + the repo's own
  standalone HM generation (incl. home-files inputDerivation) into the
  ISO — stylix re-renders base16 templates per switch and an offline
  `apply` cascaded into building stdenv from source (1107 drvs).
  Verified with tools/vm/gap-analysis.py: 17 config drvs, zero fetches.
- Stylix: track release-26.05 (kills the HM version-skew warning and
  the stale home-manager follows), lock updated.
- Roadmap: swaync (no notification daemon ships today).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Bernardo Magri
2026-06-12 17:50:55 +01:00
parent bc5faec6b8
commit dccceb4c48
7 changed files with 117 additions and 22 deletions

View File

@@ -109,6 +109,29 @@ def deep_merge(base: dict, override: dict) -> dict:
return out
# ─── Font verification ────────────────────────────────────────────────────
def check_fonts(state: dict) -> None:
"""Warn when a configured font family isn't installed. fontconfig
substitutes silently, so a typo'd or missing fonts.mono would just
render the whole desktop in some fallback with no error anywhere."""
if shutil.which("fc-match") is None:
return
for key in ("mono", "ui"):
name = (state.get("fonts") or {}).get(key)
if not name:
continue
result = subprocess.run(["fc-match", "-f", "%{family}", name],
capture_output=True, text=True)
families = [f.strip().lower() for f in result.stdout.split(",")]
if result.returncode != 0 or name.strip().lower() not in families:
fallback = result.stdout.strip() or "unknown"
print(f"nomarchy-theme-sync: warning: fonts.{key} '{name}' is not "
f"installed — fontconfig will substitute '{fallback}'",
file=sys.stderr)
notify(f"Font '{name}' is not installed — using '{fallback}'")
# ─── Rebuild dispatch ─────────────────────────────────────────────────────
def run_switch() -> None:
@@ -219,6 +242,7 @@ def cmd_apply(args) -> None:
state = deep_merge(load_state(), preset)
write_state(state)
log(f"theme: {state.get('name', args.theme)}")
check_fonts(state)
if not args.no_switch:
run_switch()
apply_wallpaper(state)
@@ -241,6 +265,8 @@ def cmd_set(args) -> None:
write_state(state)
log(f"set {args.path} = {value!r}")
if args.path.startswith("fonts."):
check_fonts(state)
if not args.no_switch:
run_switch()
apply_wallpaper(state)