summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>2022-07-29 18:01:27 +0000
committerGitHub <noreply@github.com>2022-07-29 18:01:27 +0000
commit50de8aa60e3a8768af4e31e810be456b82d89a44 (patch)
tree22aeb382a911cd8019d6f14426ea7450d098b382 /nixos
parentdb9cecdbc25319b86ad371eb45573482040ad24a (diff)
parentf0df0acc162dd31ab0b1b5f2f64394da43cf6ea0 (diff)
downloadnixpkgs-50de8aa60e3a8768af4e31e810be456b82d89a44.tar
nixpkgs-50de8aa60e3a8768af4e31e810be456b82d89a44.tar.gz
nixpkgs-50de8aa60e3a8768af4e31e810be456b82d89a44.tar.bz2
nixpkgs-50de8aa60e3a8768af4e31e810be456b82d89a44.tar.lz
nixpkgs-50de8aa60e3a8768af4e31e810be456b82d89a44.tar.xz
nixpkgs-50de8aa60e3a8768af4e31e810be456b82d89a44.tar.zst
nixpkgs-50de8aa60e3a8768af4e31e810be456b82d89a44.zip
Merge master into staging-next
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/from_md/release-notes/rl-2211.section.xml8
-rw-r--r--nixos/doc/manual/release-notes/rl-2211.section.md4
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/services/hardware/kanata.nix156
4 files changed, 169 insertions, 0 deletions
diff --git a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml
index be3adc4d3be..79f856a4093 100644
--- a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml
+++ b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml
@@ -135,6 +135,14 @@
       </listitem>
       <listitem>
         <para>
+          <link xlink:href="https://github.com/jtroo/kanata">kanata</link>,
+          a tool to improve keyboard comfort and usability with advanced
+          customization. Available as
+          <link xlink:href="options.html#opt-services.kanata.enable">services.kanata</link>.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
           <link xlink:href="https://github.com/aiberia/persistent-evdev">persistent-evdev</link>,
           a daemon to add virtual proxy devices that mirror a physical
           input device but persist even if the underlying hardware is
diff --git a/nixos/doc/manual/release-notes/rl-2211.section.md b/nixos/doc/manual/release-notes/rl-2211.section.md
index 3f9afe13f1d..607da187b89 100644
--- a/nixos/doc/manual/release-notes/rl-2211.section.md
+++ b/nixos/doc/manual/release-notes/rl-2211.section.md
@@ -58,6 +58,10 @@ In addition to numerous new and upgraded packages, this release has the followin
 
 - [infnoise](https://github.com/leetronics/infnoise), a hardware True Random Number Generator dongle.
   Available as [services.infnoise](options.html#opt-services.infnoise.enable).
+
+- [kanata](https://github.com/jtroo/kanata), a tool to improve keyboard comfort and usability with advanced customization.
+  Available as [services.kanata](options.html#opt-services.kanata.enable).
+
 - [persistent-evdev](https://github.com/aiberia/persistent-evdev), a daemon to add virtual proxy devices that mirror a physical input device but persist even if the underlying hardware is hot-plugged. Available as [services.persistent-evdev](#opt-services.persistent-evdev.enable).
 
 - [schleuder](https://schleuder.org/), a mailing list manager with PGP support. Enable using [services.schleuder](#opt-services.schleuder.enable).
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 3010a213705..d961e2f683b 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -447,6 +447,7 @@
   ./services/hardware/interception-tools.nix
   ./services/hardware/irqbalance.nix
   ./services/hardware/joycond.nix
+  ./services/hardware/kanata.nix
   ./services/hardware/lcd.nix
   ./services/hardware/lirc.nix
   ./services/hardware/nvidia-optimus.nix
diff --git a/nixos/modules/services/hardware/kanata.nix b/nixos/modules/services/hardware/kanata.nix
new file mode 100644
index 00000000000..f8250afa4a0
--- /dev/null
+++ b/nixos/modules/services/hardware/kanata.nix
@@ -0,0 +1,156 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.kanata;
+
+  keyboard = {
+    options = {
+      device = mkOption {
+        type = types.str;
+        example = "/dev/input/by-id/usb-0000_0000-event-kbd";
+        description = "Path to the keyboard device.";
+      };
+      config = mkOption {
+        type = types.lines;
+        example = ''
+          (defsrc
+            grv  1    2    3    4    5    6    7    8    9    0    -    =    bspc
+            tab  q    w    e    r    t    y    u    i    o    p    [    ]    \
+            caps a    s    d    f    g    h    j    k    l    ;    '    ret
+            lsft z    x    c    v    b    n    m    ,    .    /    rsft
+            lctl lmet lalt           spc            ralt rmet rctl)
+
+          (deflayer qwerty
+            grv  1    2    3    4    5    6    7    8    9    0    -    =    bspc
+            tab  q    w    e    r    t    y    u    i    o    p    [    ]    \
+            @cap a    s    d    f    g    h    j    k    l    ;    '    ret
+            lsft z    x    c    v    b    n    m    ,    .    /    rsft
+            lctl lmet lalt           spc            ralt rmet rctl)
+
+          (defalias
+            ;; tap within 100ms for capslk, hold more than 100ms for lctl
+            cap (tap-hold 100 100 caps lctl))
+        '';
+        description = ''
+          Configuration other than defcfg.
+          See <link xlink:href="https://github.com/jtroo/kanata"/> for more information.
+        '';
+      };
+      extraDefCfg = mkOption {
+        type = types.lines;
+        default = "";
+        example = "danger-enable-cmd yes";
+        description = ''
+          Configuration of defcfg other than linux-dev.
+          See <link xlink:href="https://github.com/jtroo/kanata"/> for more information.
+        '';
+      };
+    };
+  };
+
+  mkName = name: "kanata-${name}";
+
+  mkConfig = name: keyboard: pkgs.writeText "${mkName name}-config.kdb" ''
+    (defcfg
+      ${keyboard.extraDefCfg}
+      linux-dev ${keyboard.device})
+
+    ${keyboard.config}
+  '';
+
+  mkService = name: keyboard: nameValuePair (mkName name) {
+    description = "kanata for ${keyboard.device}";
+
+    # Because path units are used to activate service units, which
+    # will start the old stopped services during "nixos-rebuild
+    # switch", stopIfChanged here is a workaround to make sure new
+    # services are running after "nixos-rebuild switch".
+    stopIfChanged = false;
+
+    serviceConfig = {
+      ExecStart = ''
+        ${cfg.package}/bin/kanata \
+          --cfg ${mkConfig name keyboard}
+      '';
+
+      DynamicUser = true;
+      SupplementaryGroups = with config.users.groups; [
+        input.name
+        uinput.name
+      ];
+
+      # hardening
+      DeviceAllow = [
+        "/dev/uinput w"
+        "char-input r"
+      ];
+      CapabilityBoundingSet = "";
+      DevicePolicy = "closed";
+      IPAddressDeny = "any";
+      LockPersonality = true;
+      MemoryDenyWriteExecute = true;
+      PrivateNetwork = true;
+      PrivateUsers = true;
+      ProcSubset = "pid";
+      ProtectClock = true;
+      ProtectControlGroups = true;
+      ProtectHome = true;
+      ProtectHostname = true;
+      ProtectKernelLogs = true;
+      ProtectKernelModules = true;
+      ProtectKernelTunables = true;
+      ProtectProc = "invisible";
+      RestrictAddressFamilies = "none";
+      RestrictNamespaces = true;
+      RestrictRealtime = true;
+      SystemCallArchitectures = "native";
+      SystemCallFilter = [
+        "@system-service"
+        "~@privileged"
+        "~@resources"
+      ];
+      UMask = "0077";
+    };
+  };
+
+  mkPath = name: keyboard: nameValuePair (mkName name) {
+    description = "kanata trigger for ${keyboard.device}";
+    wantedBy = [ "multi-user.target" ];
+    pathConfig = {
+      PathExists = keyboard.device;
+    };
+  };
+in
+{
+  options.services.kanata = {
+    enable = mkEnableOption "kanata";
+    package = mkOption {
+      type = types.package;
+      default = pkgs.kanata;
+      defaultText = lib.literalExpression "pkgs.kanata";
+      example = lib.literalExpression "pkgs.kanata-with-cmd";
+      description = ''
+        kanata package to use.
+        If you enable danger-enable-cmd, pkgs.kanata-with-cmd should be used.
+      '';
+    };
+    keyboards = mkOption {
+      type = types.attrsOf (types.submodule keyboard);
+      default = { };
+      description = "Keyboard configurations.";
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+    hardware.uinput.enable = true;
+
+    systemd = {
+      paths = mapAttrs' mkPath cfg.keyboards;
+      services = mapAttrs' mkService cfg.keyboards;
+    };
+  };
+
+  meta.maintainers = with lib.maintainers; [ linj ];
+}