Files
Nomarchy/modules/nixos/options.nix
Bernardo Magri 52d1581131
All checks were successful
Check / eval (push) Successful in 6m16s
feat(power): suspend-then-hibernate 1h on battery (#115)
Human decision: 1h delay, battery only, Preferences enable/disable.
Wire systemd suspend-then-hibernate + HibernateDelaySec=1h +
HibernateOnACPower=false when settings.power.suspendThenHibernate is on
and boot.resumeDevice is set. Lid: s2h undocked, plain suspend on AC.
nomarchy-suspend for hypridle + Power menu (live state). LUKS unlock
before encrypted hibernate so s2h→disk is not double-password.
state-bridges assert the policy; HARDWARE-QUEUE #115 + suggested order.

V1: nix flake check --no-build. V3: bag-carry on hardware.
2026-07-15 12:13:23 +01:00

169 lines
8.0 KiB
Nix
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# System-level `nomarchy.system.*` options.
#
# Deliberately small: only things a downstream user plausibly disagrees
# with get a toggle. Everything else in the system module is set with
# lib.mkDefault, so plain NixOS options override it natively.
{ config, lib, ... }:
{
options.nomarchy.system = {
greeter.enable = lib.mkEnableOption "the greetd/tuigreet login screen" // { default = true; };
greeter.autoLogin = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
defaultText = lib.literalExpression
"(settings.greeter.autoLogin from state.json) or null";
example = "ada";
description = ''
Log this user straight into Hyprland on boot (greetd
initial_session); logging out lands on the normal greeter.
Normally you leave this alone and use System Auto-login, which
writes `settings.greeter.autoLogin` in state.json
./greeter.nix mkDefaults this option from it. The installer seeds
that state on LUKS-encrypted machines: the disk passphrase already
gates access, so a second prompt is ceremony. Setting this option by
hand pins the choice and the menu toggle can no longer move it.
'';
};
plymouth.enable = lib.mkEnableOption ''
the Nomarchy Plymouth boot splash (logo + progress + LUKS prompt),
background-tinted from state.json via nomarchy.system.stateFile.
Recolors on system rebuilds theme switches don't touch the initrd'' // { default = true; };
stateFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
example = lib.literalExpression "./state.json";
description = ''
state.json for the system-side consumers (currently the
Plymouth splash background). lib.mkFlake wires it automatically
from your flake; null falls back to the Boreal base color.
'';
};
fileManager.enable = lib.mkEnableOption ''
the Thunar GUI file manager + backend services (gvfs/tumbler/udisks2)
for point-and-click file management and the "open folder" handler.
The keyboard-driven TUI flagship (yazi) is the nomarchy.yazi.* home
option'' // { default = true; };
audio.enable = lib.mkEnableOption "the Pipewire audio stack" // { default = true; };
# default stays a plain `true` here; ./default.nix mkDefaults it from
# settings.bluetooth.enable (menu Preferences Bluetooth package). Reading
# the state in the option default is the trap ROADMAP § "NixOS-side state
# bridges (#116)" documents: `config.nomarchy.settings` does not exist on
# the NixOS side, and `or true` silently swallowed that for years.
bluetooth.enable = lib.mkEnableOption "Bluetooth support with blueman" // {
default = true;
defaultText = lib.literalExpression
"(settings.bluetooth.enable from state.json) or true";
};
autoTimezone.enable = lib.mkEnableOption ''
automatic timezone detection (geoclue + automatic-timezoned): the
system timezone and so the Waybar clock follows your location, so
travelling to another zone updates the time on its own. Off by default
(it's a location service and needs the network); toggle it from the
System menu, which lands the choice in the in-flake state file. Enabling
it unsets the static time.timeZone for you (a runtime timezone needs
/etc/localtime writable), so the menu toggle drives a system rebuild''
// { default = false; };
snapper.enable = lib.mkEnableOption ''
hourly/daily BTRFS timeline snapshots of / via snapper, plus the
`nixos-rebuild-snap` pre-rebuild-snapshot helper. No-op unless the
root filesystem is BTRFS with a /.snapshots subvolume (the installer
creates one)'';
power = {
enable = lib.mkEnableOption ''
active power management. By default ships power-profiles-daemon
the upstream-aligned power-saver/balanced/performance model,
switchable from the menu (nomarchy-menu power-profile) and shown
in Waybar on laptops plus thermald and a battery charge limit
where applicable. Harmless on desktops (the profile daemon just
offers balanced/performance)'' // { default = true; };
backend = lib.mkOption {
type = lib.types.enum [ "ppd" "tlp" ];
default = "ppd";
description = ''
Which daemon governs CPU/platform power. "ppd"
(power-profiles-daemon) is the default: a clean three-profile
model with the menu switcher and Waybar indicator. "tlp" trades
that for TLP's deeper, more aggressive battery tuning, at the
cost of the profile switcher (TLP has no profile concept). The
two manage the same knobs and are mutually exclusive.
'';
};
laptop = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Marks this machine as a laptop, gating battery-only features
(the charge limit below). The installer sets it to true when it
detects a battery at install time.
'';
};
thermal.enable = lib.mkEnableOption ''
thermald, Intel's thermal-management daemon, to avoid aggressive
throttling under sustained load. Intel-only the installer
enables it when it detects a GenuineIntel CPU. Harmless alongside
either backend'';
batteryChargeLimit = lib.mkOption {
type = lib.types.nullOr (lib.types.ints.between 50 100);
# No state bridge at eval time, by design: ./power.nix's oneshot reads
# settings.power.batteryChargeLimit out of the live state.json
# with jq at *runtime* and prefers it over this baked value, so the
# menu applies before (and without) a rebuild. This used to read
# `config.nomarchy.settings…`, which does not exist on the NixOS side
# and so was always null — dead, but harmless precisely because the
# runtime path never depended on it (ROADMAP § state bridges, #116).
default = null;
# Dell Adaptive charge mode ignores the end threshold unless we
# also select Custom (power.nix oneshot); see Latitude 5310 QA.
example = 80;
description = ''
Stop charging at this percentage to extend battery lifespan,
where the hardware exposes charge_control_end_threshold on a
system battery (type=Battery under /sys/class/power_supply;
name-agnostic BAT0, CMB0, ).
null leaves charging at the firmware default (menu writes 100).
Backend-independent: the menu applies live via sysfs (udev
GROUP=users on the threshold node) and persists settings in
theme-state; a oneshot re-applies on boot and AC replug. On
Dell (and similar) the oneshot also selects charge type Custom
Adaptive ignores the threshold while still reporting it.
Needs nomarchy.system.power.laptop.
'';
};
# #115: suspend → hibernate after 1h on battery. Default true so a
# bag-carried laptop stops draining without a menu trip; Preferences
# flips settings.power.suspendThenHibernate (state bridge). No-op
# when boot.resumeDevice is unset (no hibernate path).
suspendThenHibernate = lib.mkOption {
type = lib.types.bool;
default = true;
defaultText = lib.literalExpression
"(settings.power.suspendThenHibernate from state.json) or true";
description = ''
When true and hibernation is wired (boot.resumeDevice), idle and
undocked lid-close use systemd suspend-then-hibernate on battery:
sleep, then hibernate after HibernateDelaySec (1 hour). On AC,
plain suspend only (HibernateOnACPower=false; lid uses
HandleLidSwitchExternalPower=suspend). Toggle from System
Preferences Suspend then hibernate needs a system rebuild for
logind; nomarchy-suspend reads the live state for menu/hypridle.
'';
};
};
};
}