1 { config, lib, pkgs, ... }:
7 cfg = config.services.actkbd;
9 configFile = pkgs.writeText "actkbd.conf" ''
10 ${concatMapStringsSep "\n"
11 ({ keys, events, attributes, command, ... }:
12 ''${concatMapStringsSep "+" toString keys}:${concatStringsSep "," events}:${concatStringsSep "," attributes}:${command}''
18 bindingCfg = { ... }: {
22 type = types.listOf types.int;
23 description = lib.mdDoc "List of keycodes to match.";
27 type = types.listOf (types.enum ["key" "rep" "rel"]);
29 description = lib.mdDoc "List of events to match.";
32 attributes = mkOption {
33 type = types.listOf types.str;
35 description = lib.mdDoc "List of attributes.";
41 description = lib.mdDoc "What to run.";
60 description = lib.mdDoc ''
61 Whether to enable the {command}`actkbd` key mapping daemon.
63 Turning this on will start an {command}`actkbd`
64 instance for every evdev input that has at least one key
65 (which is okay even for systems with tiny memory footprint,
66 since actkbd normally uses \<100 bytes of memory per
69 This allows binding keys globally without the need for e.g.
75 type = types.listOf (types.submodule bindingCfg);
77 example = lib.literalExpression ''
78 [ { keys = [ 113 ]; events = [ "key" ]; command = "''${pkgs.alsa-utils}/bin/amixer -q set Master toggle"; }
81 description = lib.mdDoc ''
82 Key bindings for {command}`actkbd`.
84 See {command}`actkbd` {file}`README` for documentation.
86 The example shows a piece of what {option}`sound.mediaKeys.enable` does when enabled.
90 extraConfig = mkOption {
93 description = lib.mdDoc ''
94 Literal contents to append to the end of actkbd configuration file.
103 ###### implementation
105 config = mkIf cfg.enable {
107 services.udev.packages = lib.singleton (pkgs.writeTextFile {
108 name = "actkbd-udev-rules";
109 destination = "/etc/udev/rules.d/61-actkbd.rules";
111 ACTION=="add", SUBSYSTEM=="input", KERNEL=="event[0-9]*", ENV{ID_INPUT_KEY}=="1", TAG+="systemd", ENV{SYSTEMD_WANTS}+="actkbd@$env{DEVNAME}.service"
115 systemd.services."actkbd@" = {
117 restartIfChanged = true;
119 Description = "actkbd on %I";
120 ConditionPathExists = "%I";
124 ExecStart = "${pkgs.actkbd}/bin/actkbd -D -c ${configFile} -d %I";
129 environment.systemPackages = [ pkgs.actkbd ];