{ config, lib, pkgs, ... }: with lib; let cfg = config.services.redshift; in { options.services.redshift = { enable = mkOption { type = types.bool; default = false; description = '' Enable Redshift to change your screen's colour temperature depending on the time of day. ''; }; latitude = mkOption { type = types.nullOr types.str; default = null; description = '' Your current latitude, between -90.0 and 90.0. Must be provided along with longitude. ''; }; longitude = mkOption { type = types.nullOr types.str; default = null; description = '' Your current longitude, between between -180.0 and 180.0. Must be provided along with latitude. ''; }; provider = mkOption { type = types.enum [ "manual" "geoclue2" ]; default = "manual"; description = '' The location provider to use for determining your location. If set to manual you must also provide latitude/longitude. ''; }; 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. ''; }; }; 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. ''; }; }; package = mkOption { type = types.package; default = pkgs.redshift; defaultText = "pkgs.redshift"; description = '' redshift derivation to use. ''; }; 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 { assertions = [ { assertion = if cfg.provider == "manual" then (cfg.latitude != null && cfg.longitude != null) else (cfg.latitude == null && cfg.longitude == null); message = "Latitude and longitude must be provided together, and with provider set to null."; } ]; # needed so that .desktop files are installed, which geoclue cares about environment.systemPackages = [ cfg.package ]; services.geoclue2.enable = mkIf (cfg.provider == "geoclue2") true; systemd.user.services.redshift = let providerString = if cfg.provider == "manual" then "${cfg.latitude}:${cfg.longitude}" else cfg.provider; in { description = "Redshift colour temperature adjuster"; wantedBy = [ "graphical-session.target" ]; partOf = [ "graphical-session.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} ''; RestartSec = 3; Restart = "always"; }; }; }; }