|
|
@@ -0,0 +1,131 @@
|
|
|
+{ config
|
|
|
+, lib
|
|
|
+, pkgs
|
|
|
+, ...
|
|
|
+}:
|
|
|
+let
|
|
|
+ cfg = config.services.kanata;
|
|
|
+ driverPkg = pkgs.fetchurl {
|
|
|
+ url = "https://github.com/pqrs-org/Karabiner-DriverKit-VirtualHIDDevice/releases/download/v6.0.0/Karabiner-DriverKit-VirtualHIDDevice-6.0.0.pkg";
|
|
|
+ sha256 = "sha256-S14c06v/L/PraLekzIroG6FQnV5dpx0cyJNb9ylB458=";
|
|
|
+ };
|
|
|
+
|
|
|
+ configFile = lib.mkIf (cfg.config != "")
|
|
|
+ "${pkgs.writeScript "kanata.kbd" ("\n" + cfg.config + "\n")}";
|
|
|
+in
|
|
|
+{
|
|
|
+ options.services.kanata = {
|
|
|
+ enable = lib.mkEnableOption "kanata, a tool to improve keyboard comfort and usability with advanced customization";
|
|
|
+
|
|
|
+ package = lib.mkPackageOption pkgs "kanata" {
|
|
|
+ example = [ "kanata-with-cmd" ];
|
|
|
+ extraDescription = ''
|
|
|
+ ::: {.note}
|
|
|
+ If {option}`danger-enable-cmd` is enabled in any of the keyboards, the
|
|
|
+ `kanata-with-cmd` package should be used.
|
|
|
+ :::
|
|
|
+ '';
|
|
|
+ };
|
|
|
+
|
|
|
+ errorLogFile = lib.mkOption {
|
|
|
+ type = lib.types.path;
|
|
|
+ default = "/Library/Logs/Kanata/kanata.err.log";
|
|
|
+ example = "/Users/jsmith/Library/Logs/kanata.err.log";
|
|
|
+ description = "Path to the Kanata error log file";
|
|
|
+ };
|
|
|
+
|
|
|
+ outLogFile = lib.mkOption {
|
|
|
+ type = lib.types.path;
|
|
|
+ default = "/Library/Logs/Kanata/kanata.out.log";
|
|
|
+ example = "/Users/jsmith/Library/Logs/kanata.out.log";
|
|
|
+ description = "Path to the Kanata stdout log file";
|
|
|
+ };
|
|
|
+
|
|
|
+ config = lib.mkOption {
|
|
|
+ type = lib.types.str;
|
|
|
+ default = "";
|
|
|
+ description = "";
|
|
|
+ };
|
|
|
+ };
|
|
|
+
|
|
|
+ config = lib.mkIf cfg.enable {
|
|
|
+ environment.systemPackages = [ cfg.package ];
|
|
|
+
|
|
|
+ # Install the driver during activation
|
|
|
+ system.activationScripts.preActivation.text = ''
|
|
|
+ echo "Installing Karabiner DriverKit VirtualHIDDevice..." >&2
|
|
|
+
|
|
|
+ # Check if already installed by looking for the system extension
|
|
|
+ if ! systemextensionsctl list 2>/dev/null | grep -q "org.pqrs.Karabiner-DriverKit-VirtualHIDDevice"; then
|
|
|
+ echo "Installing driver package..." >&2
|
|
|
+ installer -pkg ${driverPkg} -target /
|
|
|
+
|
|
|
+ # Give it a moment to install
|
|
|
+ sleep 2
|
|
|
+
|
|
|
+ # Try to activate the system extension
|
|
|
+ if [ -f "/Applications/.Karabiner-VirtualHIDDevice-Manager.app/Contents/MacOS/Karabiner-VirtualHIDDevice-Manager" ]; then
|
|
|
+ echo "Activating system extension..." >&2
|
|
|
+ /Applications/.Karabiner-VirtualHIDDevice-Manager.app/Contents/MacOS/Karabiner-VirtualHIDDevice-Manager activate || {
|
|
|
+ echo "System extension activation requires user approval in System Settings > Privacy & Security" >&2
|
|
|
+ }
|
|
|
+ fi
|
|
|
+ else
|
|
|
+ echo "Karabiner DriverKit already installed" >&2
|
|
|
+ fi
|
|
|
+ '';
|
|
|
+
|
|
|
+ # Cleanup when disabled
|
|
|
+ system.activationScripts.postActivation.text = lib.mkIf (!cfg.enable) ''
|
|
|
+ echo "Cleaning up Karabiner DriverKit..." >&2
|
|
|
+
|
|
|
+ # Stop and remove launchd services
|
|
|
+ for service in org.nixos.karabiner-vhiddaemon org.nixos.karabiner-vhidmanager; do
|
|
|
+ launchctl unload "/Library/LaunchDaemons/$service.plist" 2>/dev/null || true
|
|
|
+ rm -f "/Library/LaunchDaemons/$service.plist" 2>/dev/null || true
|
|
|
+ done
|
|
|
+
|
|
|
+ # Remove the manager app copy
|
|
|
+ rm -rf /Applications/.Nix-Karabiner-DriverKit/ 2>/dev/null || true
|
|
|
+
|
|
|
+ # Note: We don't uninstall the system extension as that requires manual user action
|
|
|
+ # and the extension can be shared with other apps
|
|
|
+ echo "Note: Karabiner system extension remains installed (can be removed manually in System Settings)" >&2
|
|
|
+ '';
|
|
|
+
|
|
|
+ launchd.daemons.karabiner-vhiddaemon.serviceConfig = {
|
|
|
+ Label = "org.nixos.karabiner-vhiddaemon";
|
|
|
+ ProgramArguments = [
|
|
|
+ "/Library/Application Support/org.pqrs/Karabiner-DriverKit-VirtualHIDDevice/Applications/Karabiner-VirtualHIDDevice-Daemon.app/Contents/MacOS/Karabiner-VirtualHIDDevice-Daemon"
|
|
|
+ ];
|
|
|
+ RunAtLoad = true;
|
|
|
+ KeepAlive = true;
|
|
|
+ };
|
|
|
+
|
|
|
+ launchd.daemons.karabiner-vhidmanager.serviceConfig = {
|
|
|
+ Label = "org.nixos.karabiner-vhidmanager";
|
|
|
+ ProgramArguments = [
|
|
|
+ "/Applications/.Karabiner-VirtualHIDDevice-Manager.app/Contents/MacOS/Karabiner-VirtualHIDDevice-Manager"
|
|
|
+ "activate"
|
|
|
+ ];
|
|
|
+ RunAtLoad = true;
|
|
|
+ };
|
|
|
+
|
|
|
+ launchd.daemons.kanata.serviceConfig = {
|
|
|
+ Label = "org.nixos.kanata";
|
|
|
+ ProgramArguments = [
|
|
|
+ "${lib.getExe cfg.package}"
|
|
|
+ "--port"
|
|
|
+ "10000"
|
|
|
+ # "--debug"
|
|
|
+ ] ++ lib.optionals (cfg.config != "") [ "-c" configFile ];
|
|
|
+
|
|
|
+ RunAtLoad = true;
|
|
|
+ KeepAlive = true;
|
|
|
+ StandardOutPath = cfg.outLogFile;
|
|
|
+ StandardErrorPath = cfg.errorLogFile;
|
|
|
+ };
|
|
|
+ };
|
|
|
+
|
|
|
+ meta.maintainers = [ ];
|
|
|
+}
|