8 cfg = config.services.evremap;
9 format = pkgs.formats.toml { };
11 key = lib.types.strMatching "KEY_[[:upper:]]+" // {
12 description = "key ID prefixed with KEY_";
22 You can get a list of keys by running `evremap list-keys`.
27 (mkKeyOption description)
29 type = lib.types.listOf key;
32 dualRoleModule = lib.types.submodule {
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.";
40 remapModule = lib.types.submodule {
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.";
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;
56 device_name = lib.mkOption {
58 example = "AT Translated Set 2 keyboard";
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.
66 dual_role = lib.mkOption {
67 type = lib.types.listOf dualRoleModule;
71 input = "KEY_CAPSLOCK";
72 hold = [ "KEY_LEFTCTRL" ];
77 List of dual-role remappings that output different key sequences based on whether the
78 input key is held or tapped.
82 remap = lib.mkOption {
83 type = lib.types.listOf remapModule;
91 output = [ "KEY_PAGEUP" ];
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.
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}";
125 SupplementaryGroups = [
126 config.users.groups.input.name
127 config.users.groups.uinput.name
129 Restart = "on-failure";
135 ProtectKernelLogs = true;
136 ProtectControlGroups = true;
137 ProtectKernelModules = true;
138 ProtectHostname = true;
139 ProtectKernelTunables = true;
140 ProtectProc = "invisible";
145 PrivateNetwork = 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";