Skip to content

Instantly share code, notes, and snippets.

@xcud
Last active December 8, 2025 14:59
Show Gist options
  • Select an option

  • Save xcud/a3587af9788837b4c89aafd96c28225a to your computer and use it in GitHub Desktop.

Select an option

Save xcud/a3587af9788837b4c89aafd96c28225a to your computer and use it in GitHub Desktop.
A bash script to disable your laptop keyboard when your cat sits on it. Auto-detects common laptop keyboards (including dual-controller setups like Lenovo Ideapad). Just `chmod +x cat_mode.sh` and bind to an F key. Override detection via ~/.config/cat_mode.conf if needed.
#!/bin/bash
# Cat Mode Toggle Script
# Detects current state and toggles between enabled/disabled keyboard
MASTER_ID=3
TIMER_PID_FILE="/tmp/keyboard_timer_pid"
CONFIG_FILE="$HOME/.config/cat_mode.conf"
# Auto-detect laptop keyboard(s) - some laptops have multiple controllers
detect_keyboards() {
# If user has a config file, use that (one name per line)
if [ -f "$CONFIG_FILE" ]; then
cat "$CONFIG_FILE"
return
fi
# Common laptop keyboard patterns - check all that match
local found=""
for pattern in "AT Translated Set 2 keyboard" "Internal Keyboard" "Built-in Keyboard" "ITE Tech. Inc. ITE Device(8258) Keyboard"; do
if xinput list --name-only | grep -qF "$pattern"; then
echo "$pattern"
found="yes"
fi
done
if [ -z "$found" ]; then
echo ""
fi
}
# Get keyboard ID from name (exclude pointer devices)
get_keyboard_id() {
local name="$1"
xinput list | grep -F "$name" | grep -v "slave pointer" | grep -oP 'id=\K[0-9]+'
}
# Read detected keyboards into array
mapfile -t KEYBOARD_NAMES < <(detect_keyboards)
if [ ${#KEYBOARD_NAMES[@]} -eq 0 ] || [ -z "${KEYBOARD_NAMES[0]}" ]; then
echo "Error: Could not auto-detect laptop keyboard."
echo ""
echo "Available keyboards:"
xinput list --name-only | grep -i keyboard | while read -r kb; do
echo " - $kb"
done
echo ""
echo "To fix, save keyboard name(s) to: $CONFIG_FILE (one per line)"
echo "Example: echo 'Your Keyboard Name' > $CONFIG_FILE"
notify-send "Cat Mode Error" "Could not detect keyboard. Run script in terminal for help." -i dialog-error
exit 1
fi
# Build array of keyboard IDs
KEYBOARD_IDS=()
for name in "${KEYBOARD_NAMES[@]}"; do
id=$(get_keyboard_id "$name")
if [ -n "$id" ]; then
KEYBOARD_IDS+=("$id")
echo "Detected: $name (id=$id)"
fi
done
if [ ${#KEYBOARD_IDS[@]} -eq 0 ]; then
notify-send "Cat Mode Error" "Could not find keyboard IDs" -i dialog-error
echo "Error: Could not find any keyboard IDs"
exit 1
fi
# Function to check if keyboards are currently floating (disabled)
is_keyboard_disabled() {
# Check if first keyboard is floating (they should all be in sync)
xinput list | grep -q "id=${KEYBOARD_IDS[0]}.*floating slave"
return $?
}
# Function to disable keyboard (activate cat mode)
disable_keyboard() {
# Disable all detected keyboards
for id in "${KEYBOARD_IDS[@]}"; do
xinput float "$id"
done
# Show notification
notify-send "Cat Mode Activated" "Keyboard disabled for 30 minutes (${#KEYBOARD_IDS[@]} devices)" -i input-keyboard
echo "Keyboard disabled. It will automatically re-enable in 30 minutes."
echo "To manually toggle back, press F8 again or run this script."
# Schedule automatic re-enable in 30 minutes (1800 seconds)
# Save IDs to temp file for the timer subprocess
printf '%s\n' "${KEYBOARD_IDS[@]}" > /tmp/keyboard_ids_to_restore
(sleep 1800 && while read -r id; do xinput reattach "$id" $MASTER_ID; done < /tmp/keyboard_ids_to_restore && notify-send "Cat Mode Deactivated" "Keyboard automatically re-enabled" -i input-keyboard && rm -f $TIMER_PID_FILE /tmp/keyboard_ids_to_restore) &
# Store the background job PID
echo $! > $TIMER_PID_FILE
echo "Timer PID: $! (saved to $TIMER_PID_FILE)"
}
# Function to enable keyboard (deactivate cat mode)
enable_keyboard() {
# Re-enable all keyboards
for id in "${KEYBOARD_IDS[@]}"; do
xinput reattach "$id" $MASTER_ID
done
# Kill the timer if it's still running
if [ -f $TIMER_PID_FILE ]; then
PID=$(cat $TIMER_PID_FILE)
if kill -0 $PID 2>/dev/null; then
kill $PID
notify-send "Cat Mode Deactivated" "Timer cancelled, keyboard re-enabled" -i input-keyboard
else
notify-send "Cat Mode Deactivated" "Keyboard manually re-enabled" -i input-keyboard
fi
rm -f $TIMER_PID_FILE /tmp/keyboard_ids_to_restore
else
notify-send "Cat Mode Deactivated" "Keyboard manually re-enabled" -i input-keyboard
fi
echo "Keyboard manually re-enabled"
}
# Main logic: detect current state and toggle
if is_keyboard_disabled; then
echo "Cat mode is currently ACTIVE. Disabling cat mode..."
enable_keyboard
else
echo "Cat mode is currently INACTIVE. Activating cat mode..."
disable_keyboard
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment