fix(desktop): unfree CLI default, bar icon spacing, unified clock
All checks were successful
Check / eval (push) Successful in 3m0s

Hardware findings on Latitude: nix-shell blocked unfree; whole-swap
bars collided icon+percentage; clock needed calcurse + one module.

- Export NIXPKGS_ALLOW_UNFREE=1 + ~/.config/nixpkgs/config.nix
- Mono Nerd face + trailing spaces on battery/volume icons (all bars)
- Single clock `HH:MM · Day DD Mon`; calcurse ships with waybar
- V3 queue entries for laptop re-check

Verification: V0 — nix flake check --no-build green; V2/V3 pending on
session (user-visible bar + CLI unfree).
This commit is contained in:
2026-07-10 12:58:37 +01:00
parent eb951569cf
commit d547393e7b
13 changed files with 143 additions and 130 deletions

View File

@@ -66,6 +66,9 @@
home.sessionVariables = {
TERMINAL = config.nomarchy.terminal;
NIXOS_OZONE_WL = "1"; # Electron/Chromium native Wayland
# Same gate as modules/nixos: CLI nix-shell/shell/run for unfree pkgs
# (system nixpkgs.config alone does not cover those entry points).
NIXPKGS_ALLOW_UNFREE = "1";
# Where the Nomarchy flake (and therefore theme-state.json) lives on
# disk. nomarchy-theme-sync writes its state here; rebuilds read from
@@ -73,5 +76,12 @@
NOMARCHY_PATH = "$HOME/.nomarchy";
};
# Classic nix-shell / nix-env read this; pairs with NIXPKGS_ALLOW_UNFREE
# above so "allow unfree" is the default desktop experience, not a
# per-command export the user has to remember.
xdg.configFile."nixpkgs/config.nix".text = ''
{ allowUnfree = true; }
'';
programs.home-manager.enable = true;
}

View File

@@ -94,9 +94,9 @@ let
# A distinct --class gives the window a matchable app-id for the
# float+center+size windowrule (hyprland.nix); --gtk-single-instance=false
# forces a fresh standalone window (ghostty defaults single-instance on).
# calcurse ships uncommented in the downstream template (opt-out), so
# self-gate with a helpful notify if it's been removed. ghostty is always
# installed (ghostty.nix), so it can be relied on for the --class window.
# calcurse is installed with the bar (home.packages below); the gate is
# only for someone who force-removed it. ghostty is always installed
# (ghostty.nix), so it can be relied on for the --class window.
calendarLauncher = pkgs.writeShellScriptBin "nomarchy-calendar" ''
if ! command -v calcurse >/dev/null 2>&1; then
notify-send "Calendar" "calcurse isn't installed (removed from home.packages?)." 2>/dev/null
@@ -200,10 +200,12 @@ let
};
clock = {
format = "{:%H:%M}";
# Single module: time + short date (whole-swaps used to split these
# into clock + clock#date — one click surface for the calendar).
format = "{:%H:%M · %a %d %b}";
# Left-click → the calendar (nomarchy-calendar → calcurse in a floating
# ghostty). Replaces the old format-alt date toggle; the long date now
# rides in the tooltip's first line, so nothing is lost on hover.
# ghostty). Long weekday/month name + zone + month grid ride in the
# tooltip so the bar stays compact.
on-click = "nomarchy-calendar";
# The zone line stays live under auto-timezone (the tz-watch SIGUSR2
# reload keeps it showing the currently *detected* zone).
@@ -218,9 +220,12 @@ let
};
pulseaudio = {
format = "<span size='${toString (t.fonts.size + 2)}pt'>{icon}</span> {volume}%";
# Trailing spaces on icons (not only between span and text): Nerd Font
# glyphs often have tight right bearings and otherwise collide with
# the percentage digits.
format = "<span size='${toString (t.fonts.size + 2)}pt'>{icon}</span> {volume}%";
format-muted = "󰝟";
format-icons.default = [ "󰕿" "󰖀" "󰕾" ];
format-icons.default = [ "󰕿 " "󰖀 " "󰕾 " ];
on-click = "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle";
# Right-click → the full mixer (per-app volumes) in a floating window
# (item 35). pwvucontrol ships in the template suite; the Hyprland
@@ -246,9 +251,10 @@ let
battery = {
states = { warning = 25; critical = 10; };
# Same icon-bearing fix as pulseaudio (see format-icons note there).
format = "<span size='${toString (t.fonts.size + 2)}pt'>{icon}</span> {capacity}%";
format-charging = "<span size='${toString (t.fonts.size + 2)}pt'>󰂄</span> {capacity}%";
format-icons = [ "󰁺" "󰁼" "󰁾" "󰂀" "󰁹" ];
format-charging = "<span size='${toString (t.fonts.size + 2)}pt'>󰂄 </span>{capacity}%";
format-icons = [ "󰁺 " "󰁼 " "󰁾 " "󰂀 " "󰁹 " ];
# Click either the battery or the power-profile icon → the combined
# power menu (profile + charge cap). The granular System rows stay.
on-click = "nomarchy-menu powermgmt";
@@ -498,7 +504,8 @@ in
# The power-profile helpers on PATH, so both the generated bar and the
# whole-swap themes' static waybar.jsonc can exec them by name — plus
# the supervisor hyprland.nix exec-onces.
# the supervisor hyprland.nix exec-onces. calcurse is the clock-click
# calendar (feature dependency of the bar, not an opt-in app).
home.packages = lib.optionals config.nomarchy.waybar.enable
[ waybarSupervisor powerProfileStatus powerProfileCycle vpnStatus doctorStatus calendarLauncher ];
[ waybarSupervisor powerProfileStatus powerProfileCycle vpnStatus doctorStatus calendarLauncher pkgs.calcurse ];
}

View File

@@ -69,7 +69,11 @@ in
# GPU/wifi drivers, firmware, fonts, …). The custom nixpkgs-config
# type can't carry a nested mkDefault; disagree with
# `nixpkgs.config = lib.mkForce { allowUnfree = false; }`.
# `NIXPKGS_ALLOW_UNFREE` covers CLI `nix-shell` / `nix shell` /
# `nix run` (those ignore the system `nixpkgs.config`); pure flake
# eval still needs `--impure` when the env var is the only gate.
nixpkgs.config.allowUnfree = true;
environment.variables.NIXPKGS_ALLOW_UNFREE = "1";
# ── One keyboard layout everywhere, incl. the LUKS prompt ────────
# services.xserver.xkb.layout is the single source of truth for the