silx: 2.1.1 -> 2.1.2 (#361612)
[NixPkgs.git] / nixos / modules / services / misc / evremap.nix
blob9508955d8171327844ceaaa1d74a6af1249af24d
2   config,
3   lib,
4   pkgs,
5   ...
6 }:
7 let
8   cfg = config.services.evremap;
9   format = pkgs.formats.toml { };
11   key = lib.types.strMatching "KEY_[[:upper:]]+" // {
12     description = "key ID prefixed with KEY_";
13   };
15   mkKeyOption =
16     description:
17     lib.mkOption {
18       type = key;
19       description = ''
20         ${description}
22         You can get a list of keys by running `evremap list-keys`.
23       '';
24     };
25   mkKeySeqOption =
26     description:
27     (mkKeyOption description)
28     // {
29       type = lib.types.listOf key;
30     };
32   dualRoleModule = lib.types.submodule {
33     options = {
34       input = mkKeyOption "The key that should be remapped.";
35       hold = mkKeySeqOption "The key sequence that should be output when the input key is held.";
36       tap = mkKeySeqOption "The key sequence that should be output when the input key is tapped.";
37     };
38   };
40   remapModule = lib.types.submodule {
41     options = {
42       input = mkKeySeqOption "The key sequence that should be remapped.";
43       output = mkKeySeqOption "The key sequence that should be output when the input sequence is entered.";
44     };
45   };
48   options.services.evremap = {
49     enable = lib.mkEnableOption "evremap, a keyboard input remapper for Linux/Wayland systems";
51     settings = lib.mkOption {
52       type = lib.types.submodule {
53         freeformType = format.type;
55         options = {
56           device_name = lib.mkOption {
57             type = lib.types.str;
58             example = "AT Translated Set 2 keyboard";
59             description = ''
60               The name of the device that should be remapped.
62               You can get a list of devices by running `evremap list-devices` with elevated permissions.
63             '';
64           };
66           dual_role = lib.mkOption {
67             type = lib.types.listOf dualRoleModule;
68             default = [ ];
69             example = [
70               {
71                 input = "KEY_CAPSLOCK";
72                 hold = [ "KEY_LEFTCTRL" ];
73                 tap = [ "KEY_ESC" ];
74               }
75             ];
76             description = ''
77               List of dual-role remappings that output different key sequences based on whether the
78               input key is held or tapped.
79             '';
80           };
82           remap = lib.mkOption {
83             type = lib.types.listOf remapModule;
84             default = [ ];
85             example = [
86               {
87                 input = [
88                   "KEY_LEFTALT"
89                   "KEY_UP"
90                 ];
91                 output = [ "KEY_PAGEUP" ];
92               }
93             ];
94             description = ''
95               List of remappings.
96             '';
97           };
98         };
99       };
101       description = ''
102         Settings for evremap.
104         See the [upstream documentation](https://github.com/wez/evremap/blob/master/README.md#configuration)
105         for how to configure evremap.
106       '';
107       default = { };
108     };
109   };
111   config = lib.mkIf cfg.enable {
112     environment.systemPackages = [ pkgs.evremap ];
114     hardware.uinput.enable = true;
116     systemd.services.evremap = {
117       description = "evremap - keyboard input remapper";
118       wantedBy = [ "multi-user.target" ];
120       script = "${lib.getExe pkgs.evremap} remap ${format.generate "evremap.toml" cfg.settings}";
122       serviceConfig = {
123         DynamicUser = true;
124         User = "evremap";
125         SupplementaryGroups = [
126           config.users.groups.input.name
127           config.users.groups.uinput.name
128         ];
129         Restart = "on-failure";
130         RestartSec = 5;
131         TimeoutSec = 20;
133         # Hardening
134         ProtectClock = true;
135         ProtectKernelLogs = true;
136         ProtectControlGroups = true;
137         ProtectKernelModules = true;
138         ProtectHostname = true;
139         ProtectKernelTunables = true;
140         ProtectProc = "invisible";
141         ProtectHome = true;
142         ProcSubset = "pid";
144         PrivateTmp = true;
145         PrivateNetwork = true;
146         PrivateUsers = true;
148         RestrictRealtime = true;
149         RestrictNamespaces = true;
150         RestrictAddressFamilies = "none";
152         MemoryDenyWriteExecute = true;
153         LockPersonality = true;
154         IPAddressDeny = "any";
155         AmbientCapabilities = "";
156         CapabilityBoundingSet = "";
157         SystemCallArchitectures = "native";
158         SystemCallFilter = [
159           "@system-service"
160           "~@resources"
161           "~@privileged"
162         ];
163         UMask = "0027";
164       };
165     };
166   };