ctucx.git: nixfiles

ctucx' nixfiles

commit bdbe6062378562d6eb11b22fea582d8955a98137
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
modules/darwin/hidutil.nix
|
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"))}
+    '';
+
+  };
+}