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