Commit ca74e8999e22
Changed files (3)
modules
laptop-keyboard-inhibit
modules/laptop-keyboard-inhibit/default.nix
@@ -0,0 +1,113 @@
+# Automatically inhibit (disable) the laptop's internal keyboard when an
+# external keyboard is connected, and re-enable it on disconnect.
+#
+# Works with both USB and Bluetooth keyboards via udev rules that write
+# to the kernel's input device `inhibited` sysfs attribute (Linux 5.11+).
+#
+# Usage:
+# services.laptop-keyboard-inhibit = {
+# enable = true;
+# # Match by device name (Bluetooth keyboards, or any input device)
+# keyboards = [ "Eyelash Corne" ];
+# # Or match USB keyboards by vendor:product ID
+# usbKeyboards = [ { vendor = "3297"; product = "1969"; } ];
+# };
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+let
+ inherit (lib)
+ mkEnableOption
+ mkIf
+ mkOption
+ types
+ concatStringsSep
+ concatMapStringsSep
+ ;
+ cfg = config.services.laptop-keyboard-inhibit;
+
+ # Script that finds and inhibits/uninhibits the internal keyboard
+ # Uses by-path stable device path for i8042 (PS/2) keyboards
+ toggleScript = pkgs.writeShellScript "toggle-internal-kbd" ''
+ ACTION="$1" # "inhibit" or "uninhibit"
+
+ VALUE=1
+ if [ "$ACTION" = "uninhibit" ]; then
+ VALUE=0
+ fi
+
+ # Find the internal keyboard's inhibited file
+ # Standard PS/2 keyboard path on x86 laptops
+ for inhibit_file in /sys/devices/platform/i8042/serio*/input/input*/inhibited; do
+ if [ -f "$inhibit_file" ]; then
+ echo "$VALUE" > "$inhibit_file" 2>/dev/null || true
+ fi
+ done
+ '';
+
+ # Generate udev rules for name-based matching (Bluetooth & USB keyboards)
+ nameRules = concatMapStringsSep "\n" (name: ''
+ # Inhibit internal keyboard when "${name}" connects
+ ACTION=="add", SUBSYSTEM=="input", ATTR{name}=="${name}", RUN+="${toggleScript} inhibit"
+ ACTION=="remove", SUBSYSTEM=="input", ENV{NAME}=="${name}", RUN+="${toggleScript} uninhibit"
+ '') cfg.keyboards;
+
+ # Generate udev rules for USB vendor:product matching
+ usbRules = concatMapStringsSep "\n" (
+ kb: ''
+ # Inhibit internal keyboard when USB keyboard ${kb.vendor}:${kb.product} connects
+ ACTION=="add", SUBSYSTEM=="input", ATTR{id/vendor}=="${kb.vendor}", ATTR{id/product}=="${kb.product}", ATTR{name}!="", RUN+="${toggleScript} inhibit"
+ ACTION=="remove", SUBSYSTEM=="input", ENV{ID_VENDOR_ID}=="${kb.vendor}", ENV{ID_MODEL_ID}=="${kb.product}", RUN+="${toggleScript} uninhibit"
+ ''
+ ) cfg.usbKeyboards;
+in
+{
+ options = {
+ services.laptop-keyboard-inhibit = {
+ enable = mkEnableOption "Inhibit internal laptop keyboard when external keyboard is connected";
+
+ keyboards = mkOption {
+ type = with types; listOf str;
+ default = [ ];
+ example = [ "Eyelash Corne" "My Custom Keyboard" ];
+ description = ''
+ List of external keyboard device names to watch for.
+ When a keyboard with this name connects, the internal laptop keyboard
+ is inhibited (disabled). It is re-enabled when the external keyboard
+ disconnects.
+
+ Find your keyboard's name with: cat /proc/bus/input/devices
+ '';
+ };
+
+ usbKeyboards = mkOption {
+ type = with types; listOf (attrsOf str);
+ default = [ ];
+ example = [
+ {
+ vendor = "3297";
+ product = "1969";
+ }
+ ];
+ description = ''
+ List of USB keyboard vendor/product ID pairs to watch for.
+ Find your keyboard's IDs with: lsusb
+
+ Example: ZSA Moonlander is vendor 3297, product 1969.
+ '';
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ services.udev.extraRules = concatStringsSep "\n" (
+ lib.filter (s: s != "") [
+ nameRules
+ usbRules
+ ]
+ );
+ };
+}
systems/kyushu/extra.nix
@@ -17,6 +17,7 @@
../common/services/docker.nix
../common/services/libvirt.nix
../common/services/binfmt.nix
+ ../../modules/laptop-keyboard-inhibit
../redhat
];
@@ -32,6 +33,17 @@
];
};
+ # Auto-disable internal keyboard when Moonlander (USB) is connected
+ services.laptop-keyboard-inhibit = {
+ enable = true;
+ usbKeyboards = [
+ {
+ vendor = "3297";
+ product = "1969";
+ }
+ ];
+ };
+
services = {
getty = {
autologinOnce = true;
systems/okinawa/extra.nix
@@ -13,6 +13,7 @@
../common/services/containers.nix
../common/services/docker.nix
../common/services/prometheus-exporters-node.nix
+ ../../modules/laptop-keyboard-inhibit
];
# Gaming setup
@@ -42,6 +43,12 @@
autologinUser = "vincent";
};
+ # Auto-disable internal keyboard when Eyelash Corne (BT) is connected
+ services.laptop-keyboard-inhibit = {
+ enable = true;
+ keyboards = [ "Eyelash Corne" ];
+ };
+
# Wireguard VPN
services.wireguard = {
enable = true;