From 3eb1de3fb4a3f354712360531624c065dfa5481d Mon Sep 17 00:00:00 2001 From: hyperfekt Date: Mon, 30 Sep 2019 15:16:55 +0200 Subject: [PATCH] nixos/redshift: rework to use config files also uses an earlier target for the drm adjustment method, and allows using dawn / dusk time even if a location provider is set --- nixos/modules/services/x11/redshift.nix | 120 ++++++++++++------------ 1 file changed, 62 insertions(+), 58 deletions(-) diff --git a/nixos/modules/services/x11/redshift.nix b/nixos/modules/services/x11/redshift.nix index 21b0b33553acc..12e7b58d58470 100644 --- a/nixos/modules/services/x11/redshift.nix +++ b/nixos/modules/services/x11/redshift.nix @@ -1,4 +1,4 @@ -{ config, lib, pkgs, ... }: +{ config, lib, pkgs, options, ... }: with lib; @@ -7,6 +7,10 @@ let cfg = config.services.redshift; lcfg = config.location; + target = if (cfg.settings.redshift.adjustment-method or null) == "drm" then "basic.target" else "graphical-session.target"; + + generatedConfig = pkgs.writeText "redshift-generated.conf" (generators.toINI {} cfg.settings); + in { imports = [ @@ -23,7 +27,14 @@ in { throw "services.redshift.longitude is set to null, you can remove this" else builtins.fromJSON value)) (mkRenamedOptionModule [ "services" "redshift" "provider" ] [ "location" "provider" ]) - ]; + (mkRemovedOptionModule [ "services" "redshift" "extraOptions" ] "All Redshift configuration is now available through services.redshift.settings instead.") + ] ++ + (map (option: mkRenamedOptionModule ([ "services" "redshift" ] ++ option.old) [ "services" "redshift" "settings" "redshift" option.new ]) [ + { old = [ "temperature" "day" ]; new = "temp-day"; } + { old = [ "temperature" "night" ]; new = "temp-night"; } + { old = [ "brightness" "day" ]; new = "brightness-day"; } + { old = [ "brightness" "night" ]; new = "brightness-night"; } + ]); options.services.redshift = { enable = mkOption { @@ -35,42 +46,41 @@ in { ''; }; - temperature = { - day = mkOption { - type = types.int; - default = 5500; - description = '' - Colour temperature to use during the day, between - 1000 and 25000 K. - ''; - }; - night = mkOption { - type = types.int; - default = 3700; - description = '' - Colour temperature to use at night, between - 1000 and 25000 K. - ''; - }; + settings = mkOption { + type = with types; attrsOf (attrsOf (nullOr (oneOf [ str float bool int ]))); + default = {}; + description = '' + The configuration to pass to redshift. + See man redshift under the section + CONFIGURATION FILE for options. + ''; + example = literalExample ''{ + redshift = { + dawn-time = "05:00-06:00"; + dusk-time = "22:00-23:00"; + temp-night = 3000; + }; + };''; + apply = c: + if !(c ? redshift.dawn-time || c ? redshift.dusk-time) && !(c ? redshift.location-provider) && options.locations.provider.isDefined then + c // { + redshift.location-provider = lcfg.provider; + } + else + c; }; - brightness = { - day = mkOption { - type = types.str; - default = "1"; - description = '' - Screen brightness to apply during the day, - between 0.1 and 1.0. - ''; - }; - night = mkOption { - type = types.str; - default = "1"; - description = '' - Screen brightness to apply during the night, - between 0.1 and 1.0. - ''; - }; + configFile = mkOption { + type = types.path; + example = "~/.config/redshift/redshift.conf"; + description = '' + Configuration file for redshift. It is recommended to use the + option instead. + + + Setting this option will override any configuration file auto-generated + through the option. + ''; }; package = mkOption { @@ -82,18 +92,21 @@ in { ''; }; - extraOptions = mkOption { - type = types.listOf types.str; - default = []; - example = [ "-v" "-m randr" ]; - description = '' - Additional command-line arguments to pass to - redshift. - ''; - }; }; config = mkIf cfg.enable { + services.redshift.configFile = mkDefault generatedConfig; + + assertions = mkIf (cfg.configFile == generatedConfig) [ { + assertion = (cfg.settings ? redshift.dawn-time) == (cfg.settings ? redshift.dusk-time); + message = "Time of dawn and time of dusk must be provided together."; + } ]; + + services.redshift.settings.manual = { + lat = mkIf options.location.latitude.isDefined lcfg.latitude; + lon = mkIf options.location.longitude.isDefined lcfg.longitude; + }; + # needed so that .desktop files are installed, which geoclue cares about environment.systemPackages = [ cfg.package ]; @@ -102,23 +115,14 @@ in { isSystem = true; }; - systemd.user.services.redshift = - let - providerString = if lcfg.provider == "manual" - then "${toString lcfg.latitude}:${toString lcfg.longitude}" - else lcfg.provider; - in - { + systemd.user.services.redshift = { description = "Redshift colour temperature adjuster"; - wantedBy = [ "graphical-session.target" ]; - partOf = [ "graphical-session.target" ]; + wantedBy = [ target ]; + partOf = [ target ]; serviceConfig = { ExecStart = '' ${cfg.package}/bin/redshift \ - -l ${providerString} \ - -t ${toString cfg.temperature.day}:${toString cfg.temperature.night} \ - -b ${toString cfg.brightness.day}:${toString cfg.brightness.night} \ - ${lib.strings.concatStringsSep " " cfg.extraOptions} + -c ${cfg.configFile} ''; RestartSec = 3; Restart = "always";