Files
Nomarchy/modules/nixos/timezone.nix
Bernardo Magri d8e1a13d50
Some checks failed
Check / eval (push) Has been cancelled
refactor(#107): theme-state.json → state.json, theme-sync → state-sync
The machine flake's git-tracked settings file is system state, not
"theme" only — rename it to state.json. CLI becomes nomarchy-state-sync
with a nomarchy-theme-sync symlink for scripts and muscle memory.

Eval (mkFlake, doctor, lifecycle) still accepts theme-state.json; the
next write migrates to state.json and removes the legacy file.
Documented in MIGRATION.md; drop the CLI alias after release notes.
2026-07-15 11:26:59 +01:00

89 lines
3.7 KiB
Nix

# Automatic timezone detection (opt-in) — the system timezone, and so the
# Waybar clock, follows your location, so travelling to another zone updates
# the time on its own. Geoclue feeds `automatic-timezoned`, which drives
# /etc/localtime at runtime.
#
# In-flake state, menu-driven (the keyboard/night-light philosophy): the on/off
# flag lives in the same state.json under `settings.autoTimezone`
# (git-tracked, reproducible), written by the System-menu toggle
# (nomarchy-autotimezone). Because this is a SYSTEM service — not a user unit it
# can start/stop instantly like night-light — the toggle drives a system rebuild
# (plus a home switch for the Waybar-refresh watcher in timezone.nix home-side).
{ config, lib, pkgs, ... }:
let
cfg = config.nomarchy.system;
# Read the same state file the rest of the system side uses (Plymouth too),
# wired by lib.mkFlake. The flag defaults off when stateFile is null;
# a set-but-missing/invalid path fails closed via state-read.nix.
state =
if cfg.stateFile != null
then import ../state-read.nix { inherit lib; } cfg.stateFile
else { };
stateEnabled = (state.settings or { }).autoTimezone or false;
sync = lib.getExe pkgs.nomarchy-state-sync;
# Menu/CLI toggle. Runs as the normal user (it owns the flake checkout +
# writes the state); sudos only the system switch, like sys-update. Writes
# the in-flake flag, then rebuilds: the system rebuild bakes the service +
# the time.timeZone override, the home switch installs/removes the Waybar
# refresh watcher — both read the same flag we just wrote.
nomarchy-autotimezone = pkgs.writeShellScriptBin "nomarchy-autotimezone" ''
set -e
if [ "$(id -u)" -eq 0 ]; then
echo "nomarchy-autotimezone: run as your normal user (it sudos the rebuild itself)" >&2
exit 1
fi
flake="''${NOMARCHY_PATH:-$HOME/.nomarchy}"
cur=$(${sync} get settings.autoTimezone 2>/dev/null) || cur=false
case "''${1:-toggle}" in
on) new=true ;;
off) new=false ;;
toggle) case "$cur" in true|True) new=false ;; *) new=true ;; esac ;;
status) echo "$cur"; exit 0 ;;
*) echo "usage: nomarchy-autotimezone [toggle|on|off|status]" >&2; exit 64 ;;
esac
${sync} --quiet set settings.autoTimezone "$new" --no-switch
if [ "$new" = true ]; then
notify-send "Auto timezone" "Enabling rebuilding the system" 2>/dev/null || true
else
notify-send "Auto timezone" "Disabling rebuilding the system" 2>/dev/null || true
fi
sudo nixos-rebuild switch --flake "$flake#default"
home-manager switch --flake "$flake"
if [ "$new" = true ]; then
notify-send "Auto timezone on" "The clock now follows your location." 2>/dev/null || true
else
notify-send "Auto timezone off" "Back to the fixed timezone in system.nix." 2>/dev/null || true
fi
'';
in
{
config = lib.mkMerge [
{
# Shipped unconditionally so the menu can enable the feature even while
# it's off. Track the in-flake flag; mkDefault so a hand-set
# nomarchy.system.autoTimezone.enable in system.nix still wins.
environment.systemPackages = [ nomarchy-autotimezone ];
nomarchy.system.autoTimezone.enable = lib.mkDefault stateEnabled;
}
(lib.mkIf cfg.autoTimezone.enable {
services.geoclue2.enable = true;
services.automatic-timezoned.enable = true;
# A runtime timezone needs /etc/localtime writable. automatic-timezoned
# sets time.timeZone = null itself, but the installer writes a static
# value at normal priority, which would collide (a hard eval error) —
# mkForce null overrides both and resolves cleanly.
time.timeZone = lib.mkForce null;
})
];
}