commit bdbe6062378562d6eb11b22fea582d8955a98137
parent 6627b58ecca47d59b9a2b91b64d8c1bb821071a5
Author: Leah (ctucx) <leah@ctu.cx>
Date: Sun, 12 Jun 2022 11:17:32 +0200
parent 6627b58ecca47d59b9a2b91b64d8c1bb821071a5
Author: Leah (ctucx) <leah@ctu.cx>
Date: Sun, 12 Jun 2022 11:17:32 +0200
modules/darwin: add hidutil module (allows remapping of keys)
1 file changed, 98 insertions(+), 0 deletions(-)
A
|
98
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/modules/darwin/hidutil.nix b/modules/darwin/hidutil.nix @@ -0,0 +1,98 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.hidutil; + + XPCEventStreamHandler = pkgs.callPackage ../../pkgs/XPCEventStreamHandler {}; + + # convert hex to int with nix! + pow = base: exp: lib.foldl' (a: x: x * a) 1 (lib.genList (_: base) exp); + hexToDec = v: + let + hexToInt = { "0" = 0; "1" = 1; "2" = 2; "3" = 3; "4" = 4; "5" = 5; "6" = 6; "7" = 7; "8" = 8; "9" = 9; "a" = 10; "b" = 11; "c" = 12;"d" = 13; "e" = 14; "f" = 15; }; + chars = lib.stringToCharacters v; + charsLen = lib.length chars; + in lib.foldl (a: v: a + v) 0 (lib.imap0 (k: v: hexToInt."${v}" * (pow 16 (charsLen - k - 1))) chars); + +in { + ###### interface + options = { + hidutil = { + + enable = mkEnableOption + "Syncthing, a self-hosted open-source alternative to Dropbox and Bittorrent Sync"; + + remapKeys = mkOption { + type = types.listOf (types.submodule { + options = { + + VendorID = mkOption { + type = types.str; + }; + + ProductID = mkOption { + type = types.str; + }; + + UserKeyMapping = mkOption { + type = types.listOf (types.submodule { + options = { + HIDKeyboardModifierMappingSrc = mkOption { + type = types.int; + }; + HIDKeyboardModifierMappingDst = mkOption { + type = types.int; + }; + }; + }); + }; + + }; + }); + default = []; + }; + + }; + }; + + ###### implementation + config = mkIf cfg.enable { + + launchd.user.agents = builtins.listToAttrs (lib.forEach cfg.remapKeys (entry: { + name = "activateUserKeyMapping-${entry.VendorID}:${entry.ProductID}"; + value.serviceConfig = { + Disabled = if (entry.VendorID != "5ac" && entry.ProductID != "281") then false else true; + Label = "org.nixos.activateUserKeyMapping-${entry.VendorID}:${entry.ProductID}"; + + ProgramArguments = [ + "${XPCEventStreamHandler}/bin/xpc_set_event_stream_handler" + "${pkgs.writeScript "hidutil" '' + #!/usr/bin/env bash + osascript -e 'display notification "Load UserKeyMapping for ${entry.VendorID}:${entry.ProductID}" with title "hidutil"' + hidutil property --matching '{"VendorID":0x${entry.VendorID},"ProductID":0x${entry.ProductID}}' --set '{"UserKeyMapping":${builtins.toJSON entry.UserKeyMapping}}' > /dev/null + ''}" + ]; + + LaunchEvents = { + "com.apple.iokit.matching" = { + "com.apple.device-attach" = { + IOMatchLaunchStream = true; + IOProviderClass = "IOUSBDevice"; + idVendor = hexToDec entry.VendorID; + idProduct = hexToDec entry.ProductID; + }; + }; + }; + }; + })); + + system.activationScripts.keyboard.text = '' + # Configuring keyboard + echo "configuring keyboard..." >&2 + ${lib.concatStringsSep "\n" (lib.forEach cfg.remapKeys (entry: "hidutil property --matching '{\"VendorID\":0x${entry.VendorID},\"ProductID\":0x${entry.ProductID}}' --set '{\"UserKeyMapping\":${builtins.toJSON entry.UserKeyMapping}}' > /dev/null"))} + ''; + + }; +}