From 41e907f884b5a2da94dae41e6195469359b09f5c Mon Sep 17 00:00:00 2001 From: Leah Amelia Chen Date: Thu, 31 Oct 2024 23:11:07 +0100 Subject: [PATCH] nixos/evremap: init module --- .../manual/release-notes/rl-2411.section.md | 2 + nixos/modules/module-list.nix | 1 + nixos/modules/services/misc/evremap.nix | 167 ++++++++++++++++++ 3 files changed, 170 insertions(+) create mode 100644 nixos/modules/services/misc/evremap.nix diff --git a/nixos/doc/manual/release-notes/rl-2411.section.md b/nixos/doc/manual/release-notes/rl-2411.section.md index 73ccad6714df..9ea2e8b5a5ed 100644 --- a/nixos/doc/manual/release-notes/rl-2411.section.md +++ b/nixos/doc/manual/release-notes/rl-2411.section.md @@ -121,6 +121,8 @@ - [HomeBox](https://github.com/sysadminsmedia/homebox), an inventory and organization system built for the home user. Available as [services.homebox](#opt-services.homebox.enable). +- [evremap](https://github.com/wez/evremap), a keyboard input remapper for Linux/Wayland systems. Available as [services.evremap](options.html#opt-services.evremap). + - [matrix-hookshot](https://matrix-org.github.io/matrix-hookshot), a Matrix bot for connecting to external services. Available as [services.matrix-hookshot](#opt-services.matrix-hookshot.enable). - [Renovate](https://github.com/renovatebot/renovate), a dependency updating tool for various Git forges and language ecosystems. Available as [services.renovate](#opt-services.renovate.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 0537dbf3ad1c..eef106a91229 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -752,6 +752,7 @@ ./services/misc/etebase-server.nix ./services/misc/etesync-dav.nix ./services/misc/evdevremapkeys.nix + ./services/misc/evremap.nix ./services/misc/felix.nix ./services/misc/flaresolverr.nix ./services/misc/forgejo.nix diff --git a/nixos/modules/services/misc/evremap.nix b/nixos/modules/services/misc/evremap.nix new file mode 100644 index 000000000000..9508955d8171 --- /dev/null +++ b/nixos/modules/services/misc/evremap.nix @@ -0,0 +1,167 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.services.evremap; + format = pkgs.formats.toml { }; + + key = lib.types.strMatching "KEY_[[:upper:]]+" // { + description = "key ID prefixed with KEY_"; + }; + + mkKeyOption = + description: + lib.mkOption { + type = key; + description = '' + ${description} + + You can get a list of keys by running `evremap list-keys`. + ''; + }; + mkKeySeqOption = + description: + (mkKeyOption description) + // { + type = lib.types.listOf key; + }; + + dualRoleModule = lib.types.submodule { + options = { + input = mkKeyOption "The key that should be remapped."; + hold = mkKeySeqOption "The key sequence that should be output when the input key is held."; + tap = mkKeySeqOption "The key sequence that should be output when the input key is tapped."; + }; + }; + + remapModule = lib.types.submodule { + options = { + input = mkKeySeqOption "The key sequence that should be remapped."; + output = mkKeySeqOption "The key sequence that should be output when the input sequence is entered."; + }; + }; +in +{ + options.services.evremap = { + enable = lib.mkEnableOption "evremap, a keyboard input remapper for Linux/Wayland systems"; + + settings = lib.mkOption { + type = lib.types.submodule { + freeformType = format.type; + + options = { + device_name = lib.mkOption { + type = lib.types.str; + example = "AT Translated Set 2 keyboard"; + description = '' + The name of the device that should be remapped. + + You can get a list of devices by running `evremap list-devices` with elevated permissions. + ''; + }; + + dual_role = lib.mkOption { + type = lib.types.listOf dualRoleModule; + default = [ ]; + example = [ + { + input = "KEY_CAPSLOCK"; + hold = [ "KEY_LEFTCTRL" ]; + tap = [ "KEY_ESC" ]; + } + ]; + description = '' + List of dual-role remappings that output different key sequences based on whether the + input key is held or tapped. + ''; + }; + + remap = lib.mkOption { + type = lib.types.listOf remapModule; + default = [ ]; + example = [ + { + input = [ + "KEY_LEFTALT" + "KEY_UP" + ]; + output = [ "KEY_PAGEUP" ]; + } + ]; + description = '' + List of remappings. + ''; + }; + }; + }; + + description = '' + Settings for evremap. + + See the [upstream documentation](https://github.com/wez/evremap/blob/master/README.md#configuration) + for how to configure evremap. + ''; + default = { }; + }; + }; + + config = lib.mkIf cfg.enable { + environment.systemPackages = [ pkgs.evremap ]; + + hardware.uinput.enable = true; + + systemd.services.evremap = { + description = "evremap - keyboard input remapper"; + wantedBy = [ "multi-user.target" ]; + + script = "${lib.getExe pkgs.evremap} remap ${format.generate "evremap.toml" cfg.settings}"; + + serviceConfig = { + DynamicUser = true; + User = "evremap"; + SupplementaryGroups = [ + config.users.groups.input.name + config.users.groups.uinput.name + ]; + Restart = "on-failure"; + RestartSec = 5; + TimeoutSec = 20; + + # Hardening + ProtectClock = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + ProtectKernelModules = true; + ProtectHostname = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProtectHome = true; + ProcSubset = "pid"; + + PrivateTmp = true; + PrivateNetwork = true; + PrivateUsers = true; + + RestrictRealtime = true; + RestrictNamespaces = true; + RestrictAddressFamilies = "none"; + + MemoryDenyWriteExecute = true; + LockPersonality = true; + IPAddressDeny = "any"; + AmbientCapabilities = ""; + CapabilityBoundingSet = ""; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@system-service" + "~@resources" + "~@privileged" + ]; + UMask = "0027"; + }; + }; + }; +}