at 25.11-pre 3.3 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 9 cfg = config.services.triggerhappy; 10 11 socket = "/run/thd.socket"; 12 13 configFile = pkgs.writeText "triggerhappy.conf" '' 14 ${lib.concatMapStringsSep "\n" ( 15 { 16 keys, 17 event, 18 cmd, 19 ... 20 }: 21 ''${lib.concatMapStringsSep "+" (x: "KEY_" + x) keys} ${ 22 toString 23 { 24 press = 1; 25 hold = 2; 26 release = 0; 27 } 28 .${event} 29 } ${cmd}'' 30 ) cfg.bindings} 31 ${cfg.extraConfig} 32 ''; 33 34 bindingCfg = 35 { ... }: 36 { 37 options = { 38 39 keys = lib.mkOption { 40 type = lib.types.listOf lib.types.str; 41 description = "List of keys to match. Key names as defined in linux/input-event-codes.h"; 42 }; 43 44 event = lib.mkOption { 45 type = lib.types.enum [ 46 "press" 47 "hold" 48 "release" 49 ]; 50 default = "press"; 51 description = "Event to match."; 52 }; 53 54 cmd = lib.mkOption { 55 type = lib.types.str; 56 description = "What to run."; 57 }; 58 59 }; 60 }; 61 62in 63 64{ 65 66 ###### interface 67 68 options = { 69 70 services.triggerhappy = { 71 72 enable = lib.mkOption { 73 type = lib.types.bool; 74 default = false; 75 description = '' 76 Whether to enable the {command}`triggerhappy` hotkey daemon. 77 ''; 78 }; 79 80 user = lib.mkOption { 81 type = lib.types.str; 82 default = "nobody"; 83 example = "root"; 84 description = '' 85 User account under which {command}`triggerhappy` runs. 86 ''; 87 }; 88 89 bindings = lib.mkOption { 90 type = lib.types.listOf (lib.types.submodule bindingCfg); 91 default = [ ]; 92 example = lib.literalExpression '' 93 [ { keys = ["PLAYPAUSE"]; cmd = "''${lib.getExe pkgs.mpc} -q toggle"; } ] 94 ''; 95 description = '' 96 Key bindings for {command}`triggerhappy`. 97 ''; 98 }; 99 100 extraConfig = lib.mkOption { 101 type = lib.types.lines; 102 default = ""; 103 description = '' 104 Literal contents to append to the end of {command}`triggerhappy` configuration file. 105 ''; 106 }; 107 108 }; 109 110 }; 111 112 ###### implementation 113 114 config = lib.mkIf cfg.enable { 115 116 systemd.sockets.triggerhappy = { 117 description = "Triggerhappy Socket"; 118 wantedBy = [ "sockets.target" ]; 119 socketConfig.ListenDatagram = socket; 120 }; 121 122 systemd.services.triggerhappy = { 123 wantedBy = [ "multi-user.target" ]; 124 description = "Global hotkey daemon"; 125 documentation = [ "man:thd(1)" ]; 126 serviceConfig = { 127 ExecStart = "${pkgs.triggerhappy}/bin/thd ${ 128 lib.optionalString (cfg.user != "root") "--user ${cfg.user}" 129 } --socket ${socket} --triggers ${configFile} --deviceglob /dev/input/event*"; 130 }; 131 }; 132 133 services.udev.packages = lib.singleton ( 134 pkgs.writeTextFile { 135 name = "triggerhappy-udev-rules"; 136 destination = "/etc/udev/rules.d/61-triggerhappy.rules"; 137 text = '' 138 ACTION=="add", SUBSYSTEM=="input", KERNEL=="event[0-9]*", ATTRS{name}!="triggerhappy", \ 139 RUN+="${pkgs.triggerhappy}/bin/th-cmd --socket ${socket} --passfd --udev" 140 ''; 141 } 142 ); 143 144 }; 145 146}