Commit 70641f9970d9
Changed files (1)
modules
laptop-keyboard-inhibit
modules/laptop-keyboard-inhibit/default.nix
@@ -25,13 +25,12 @@ let
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
+ # Searches for keyboards by name pattern (works for both PS/2 and USB internal keyboards)
toggleScript = pkgs.writeShellScript "toggle-internal-kbd" ''
ACTION="$1" # "inhibit" or "uninhibit"
@@ -40,22 +39,26 @@ let
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
+ # Find internal keyboard by common name patterns
+ # Matches: "AT Translated Set 2 keyboard", "Asus Keyboard", etc.
+ for input_dir in /sys/class/input/input*/; do
+ if [ ! -f "$input_dir/name" ]; then
+ continue
+ fi
+
+ name=$(cat "$input_dir/name")
+
+ # Match internal laptop keyboards (not external devices)
+ if echo "$name" | grep -qiE "(AT Translated|Asus Keyboard|Internal Keyboard|Laptop Keyboard)"; then
+ inhibit_file="$input_dir/inhibited"
+ if [ -f "$inhibit_file" ]; then
+ echo "$VALUE" > "$inhibit_file" 2>/dev/null && \
+ echo "[$ACTION] $name" || true
+ fi
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
@@ -114,6 +117,10 @@ in
after = [ "bluetooth.service" ];
requires = [ "bluetooth.service" ];
wantedBy = [ "multi-user.target" ];
+ path = with pkgs; [
+ bluez
+ gawk
+ ];
serviceConfig = {
Type = "simple";
@@ -128,7 +135,7 @@ in
getDeviceScript = pkgs.writeShellScript "get-bt-devices" ''
# Wait for bluetooth to be ready
sleep 2
-
+
# Find MAC addresses for configured keyboard names
${concatMapStringsSep "\n" (name: ''
MAC=$(bluetoothctl devices | grep -i "${name}" | awk '{print $2}' | head -1)
@@ -140,17 +147,17 @@ in
in
''
set -euo pipefail
-
+
# Get MAC addresses of configured keyboards
MACS=$(${getDeviceScript})
-
+
if [ -z "$MACS" ]; then
echo "No Bluetooth keyboards found. Make sure they are paired."
echo "Use: bluetoothctl pair <MAC>"
sleep 10
exit 1
fi
-
+
# Monitor each keyboard
while IFS= read -r MAC; do
(
@@ -167,7 +174,7 @@ in
done
) &
done <<< "$MACS"
-
+
# Wait for all background monitors
wait
'';