summary refs log blame commit diff
path: root/nixos/modules/hardware/openrazer.nix
blob: b5c3d67441422c01aca637077bf5690963f10b28 (plain) (tree)


















































                                                                                         
                                                                       
















































































                                                                               
{ config, pkgs, lib, ... }:

with lib;

let
  cfg = config.hardware.openrazer;
  kernelPackages = config.boot.kernelPackages;

  toPyBoolStr = b: if b then "True" else "False";

  daemonExe = "${pkgs.openrazer-daemon}/bin/openrazer-daemon --config ${daemonConfFile}";

  daemonConfFile = pkgs.writeTextFile {
    name = "razer.conf";
    text = ''
      [General]
      verbose_logging = ${toPyBoolStr cfg.verboseLogging}

      [Startup]
      sync_effects_enabled = ${toPyBoolStr cfg.syncEffectsEnabled}
      devices_off_on_screensaver = ${toPyBoolStr cfg.devicesOffOnScreensaver}
      mouse_battery_notifier = ${toPyBoolStr cfg.mouseBatteryNotifier}

      [Statistics]
      key_statistics = ${toPyBoolStr cfg.keyStatistics}
    '';
  };

  dbusServiceFile = pkgs.writeTextFile rec {
    name = "org.razer.service";
    destination = "/share/dbus-1/services/${name}";
    text = ''
      [D-BUS Service]
      Name=org.razer
      Exec=${daemonExe}
      SystemdService=openrazer-daemon.service
    '';
  };

  drivers = [
    "razerkbd"
    "razermouse"
    "razerfirefly"
    "razerkraken"
    "razermug"
    "razercore"
  ];
in
{
  options = {
    hardware.openrazer = {
      enable = mkEnableOption "OpenRazer drivers and userspace daemon";

      verboseLogging = mkOption {
        type = types.bool;
        default = false;
        description = ''
          Whether to enable verbose logging. Logs debug messages.
        '';
      };

      syncEffectsEnabled = mkOption {
        type = types.bool;
        default = true;
        description = ''
          Set the sync effects flag to true so any assignment of
          effects will work across devices.
        '';
      };

      devicesOffOnScreensaver = mkOption {
        type = types.bool;
        default = true;
        description = ''
          Turn off the devices when the systems screensaver kicks in.
        '';
      };

      mouseBatteryNotifier = mkOption {
        type = types.bool;
        default = true;
        description = ''
          Mouse battery notifier.
        '';
      };

      keyStatistics = mkOption {
        type = types.bool;
        default = false;
        description = ''
          Collects number of keypresses per hour per key used to
          generate a heatmap.
        '';
      };
    };
  };

  config = mkIf cfg.enable {
    boot.extraModulePackages = [ kernelPackages.openrazer ];
    boot.kernelModules = drivers;

    # Makes the man pages available so you can succesfully run
    # > systemctl --user help openrazer-daemon
    environment.systemPackages = [ pkgs.python3Packages.openrazer-daemon.man ];

    services.udev.packages = [ kernelPackages.openrazer ];
    services.dbus.packages = [ dbusServiceFile ];

    # A user must be a member of the plugdev group in order to start
    # the openrazer-daemon. Therefore we make sure that the plugdev
    # group exists.
    users.groups.plugdev = {};

    systemd.user.services.openrazer-daemon = {
      description = "Daemon to manage razer devices in userspace";
      unitConfig.Documentation = "man:openrazer-daemon(8)";
        # Requires a graphical session so the daemon knows when the screensaver
        # starts. See the 'devicesOffOnScreensaver' option.
        wantedBy = [ "graphical-session.target" ];
        partOf = [ "graphical-session.target" ];
        serviceConfig = {
          Type = "dbus";
          BusName = "org.razer";
          ExecStart = "${daemonExe} --foreground";
          Restart = "always";
      };
    };
  };

  meta = {
    maintainers = with lib.maintainers; [ roelvandijk ];
  };
}