feat(system): add laptop power preset module
New `nomarchy.system.laptop.{enable,thermald}` options. `enable`
defaults to `formFactor == "laptop"`, so the installer's existing
formFactor write auto-flips the preset on without installer changes.
The module wires TLP (governors + 75/80 charge thresholds),
force-disables power-profiles-daemon (mutually exclusive with TLP),
enables upower and thermald (x86_64), adds the brightnessctl udev
rule so the existing brightness scripts work without root, and sets
a logind lid-switch policy that resolves to suspend-then-hibernate
when `hibernation.enable` is on, plain suspend otherwise.
Closes the "Form-factor → laptop preset auto-enable" Now item and
the "Laptop preset module" Next item from docs/ROADMAP.md in one
change.
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
./browser.nix
|
||||
# Tier 1 system features (all opt-in via nomarchy.system.*).
|
||||
./snapper.nix
|
||||
./laptop.nix
|
||||
./hibernate.nix
|
||||
./containers.nix
|
||||
./pam.nix
|
||||
|
||||
42
core/system/laptop.nix
Normal file
42
core/system/laptop.nix
Normal file
@@ -0,0 +1,42 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.nomarchy.system.laptop;
|
||||
hib = config.nomarchy.system.hibernation;
|
||||
lidAction = if hib.enable then "suspend-then-hibernate" else "suspend";
|
||||
in
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.tlp = {
|
||||
enable = lib.mkDefault true;
|
||||
settings = {
|
||||
CPU_SCALING_GOVERNOR_ON_AC = lib.mkDefault "performance";
|
||||
CPU_SCALING_GOVERNOR_ON_BAT = lib.mkDefault "powersave";
|
||||
CPU_BOOST_ON_BAT = lib.mkDefault 0;
|
||||
PLATFORM_PROFILE_ON_AC = lib.mkDefault "balanced";
|
||||
PLATFORM_PROFILE_ON_BAT = lib.mkDefault "low-power";
|
||||
# Charge thresholds only honored on supported hardware (ThinkPad,
|
||||
# some ASUS); a harmless warning is logged elsewhere.
|
||||
START_CHARGE_THRESH_BAT0 = lib.mkDefault 75;
|
||||
STOP_CHARGE_THRESH_BAT0 = lib.mkDefault 80;
|
||||
};
|
||||
};
|
||||
|
||||
# TLP and power-profiles-daemon both arbitrate CPU/EPP — NixOS asserts
|
||||
# mutual exclusion. Opt out of the preset entirely to use PPD instead.
|
||||
services.power-profiles-daemon.enable = lib.mkForce false;
|
||||
|
||||
services.upower.enable = lib.mkDefault true;
|
||||
services.thermald.enable = lib.mkDefault cfg.thermald;
|
||||
|
||||
# Backlight write access for the `video` group, so the existing
|
||||
# nomarchy-brightness-{display,keyboard} scripts run without root.
|
||||
services.udev.packages = [ pkgs.brightnessctl ];
|
||||
|
||||
services.logind.settings.Login = {
|
||||
HandleLidSwitch = lib.mkDefault lidAction;
|
||||
HandleLidSwitchExternalPower = lib.mkDefault "suspend";
|
||||
HandleLidSwitchDocked = lib.mkDefault "ignore";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
{ lib, ... }:
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
options.nomarchy.system = {
|
||||
@@ -82,6 +82,32 @@
|
||||
};
|
||||
};
|
||||
|
||||
laptop = {
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = config.nomarchy.system.formFactor == "laptop";
|
||||
defaultText = lib.literalExpression ''config.nomarchy.system.formFactor == "laptop"'';
|
||||
description = ''
|
||||
Laptop power preset: TLP (with sane AC/battery governors),
|
||||
`services.upower`, `services.thermald` (x86_64), a brightnessctl
|
||||
udev rule, and a logind lid-switch policy. Force-disables
|
||||
`services.power-profiles-daemon` (mutually exclusive with TLP).
|
||||
Lid-close defers to `nomarchy.system.hibernation.enable`:
|
||||
suspend-then-hibernate when on, suspend otherwise. Defaults on
|
||||
when `formFactor = "laptop"`.
|
||||
'';
|
||||
};
|
||||
thermald = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = pkgs.stdenv.hostPlatform.isx86_64;
|
||||
defaultText = lib.literalExpression "pkgs.stdenv.hostPlatform.isx86_64";
|
||||
description = ''
|
||||
Enable `services.thermald` (Intel thermal daemon). Default true on
|
||||
x86_64. Harmless no-op on AMD; gated off on aarch64.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
containers = {
|
||||
enable = lib.mkEnableOption ''
|
||||
Rootless Podman with Docker compatibility (`docker` → `podman`),
|
||||
|
||||
Reference in New Issue
Block a user