1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.services.redshift;
8 lcfg = config.location;
9
10in {
11
12 imports = [
13 (mkChangedOptionModule [ "services" "redshift" "latitude" ] [ "location" "latitude" ]
14 (config:
15 let value = getAttrFromPath [ "services" "redshift" "latitude" ] config;
16 in if value == null then
17 throw "services.redshift.latitude is set to null, you can remove this"
18 else builtins.fromJSON value))
19 (mkChangedOptionModule [ "services" "redshift" "longitude" ] [ "location" "longitude" ]
20 (config:
21 let value = getAttrFromPath [ "services" "redshift" "longitude" ] config;
22 in if value == null then
23 throw "services.redshift.longitude is set to null, you can remove this"
24 else builtins.fromJSON value))
25 (mkRenamedOptionModule [ "services" "redshift" "provider" ] [ "location" "provider" ])
26 ];
27
28 options.services.redshift = {
29 enable = mkOption {
30 type = types.bool;
31 default = false;
32 description = ''
33 Enable Redshift to change your screen's colour temperature depending on
34 the time of day.
35 '';
36 };
37
38 temperature = {
39 day = mkOption {
40 type = types.int;
41 default = 5500;
42 description = ''
43 Colour temperature to use during the day, between
44 `1000` and `25000` K.
45 '';
46 };
47 night = mkOption {
48 type = types.int;
49 default = 3700;
50 description = ''
51 Colour temperature to use at night, between
52 `1000` and `25000` K.
53 '';
54 };
55 };
56
57 brightness = {
58 day = mkOption {
59 type = types.str;
60 default = "1";
61 description = ''
62 Screen brightness to apply during the day,
63 between `0.1` and `1.0`.
64 '';
65 };
66 night = mkOption {
67 type = types.str;
68 default = "1";
69 description = ''
70 Screen brightness to apply during the night,
71 between `0.1` and `1.0`.
72 '';
73 };
74 };
75
76 package = mkPackageOption pkgs "redshift" { };
77
78 executable = mkOption {
79 type = types.str;
80 default = "/bin/redshift";
81 example = "/bin/redshift-gtk";
82 description = ''
83 Redshift executable to use within the package.
84 '';
85 };
86
87 extraOptions = mkOption {
88 type = types.listOf types.str;
89 default = [];
90 example = [ "-v" "-m randr" ];
91 description = ''
92 Additional command-line arguments to pass to
93 {command}`redshift`.
94 '';
95 };
96 };
97
98 config = mkIf cfg.enable {
99 # needed so that .desktop files are installed, which geoclue cares about
100 environment.systemPackages = [ cfg.package ];
101
102 services.geoclue2.appConfig.redshift = {
103 isAllowed = true;
104 isSystem = true;
105 };
106
107 systemd.user.services.redshift =
108 let
109 providerString = if lcfg.provider == "manual"
110 then "${toString lcfg.latitude}:${toString lcfg.longitude}"
111 else lcfg.provider;
112 in
113 {
114 description = "Redshift colour temperature adjuster";
115 wantedBy = [ "graphical-session.target" ];
116 partOf = [ "graphical-session.target" ];
117 serviceConfig = {
118 ExecStart = ''
119 ${cfg.package}${cfg.executable} \
120 -l ${providerString} \
121 -t ${toString cfg.temperature.day}:${toString cfg.temperature.night} \
122 -b ${toString cfg.brightness.day}:${toString cfg.brightness.night} \
123 ${lib.strings.concatStringsSep " " cfg.extraOptions}
124 '';
125 RestartSec = 3;
126 Restart = "always";
127 };
128 };
129 };
130
131}