Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 70 additions & 45 deletions scripts/MapNitroButton.sh
Original file line number Diff line number Diff line change
@@ -1,58 +1,83 @@
#!/bin/bash

# Function to set up device permissions
setup_permissions() {
echo "Setting up permissions..."

# Add user to input group if not already
if ! groups | grep -q '\binput\b'; then
echo "Adding user $USER to 'input' group..."
usermod -a -G input $USER
echo "Note: You'll need to log out and back in for group changes to take effect."
fi

# Create udev rule if needed
UDEV_RULE="/etc/udev/rules.d/99-input.rules"
if [ ! -f "$UDEV_RULE" ] || ! grep -q 'MODE="0660"' "$UDEV_RULE"; then
echo "Creating udev rules file..."
echo 'KERNEL=="event*", SUBSYSTEM=="input", MODE="0660", GROUP="input"' > /tmp/input.rules
mv /tmp/input.rules "$UDEV_RULE"
chmod 644 "$UDEV_RULE"
udevadm control --reload-rules
udevadm trigger
echo "Permissions rules updated."
# --- CONFIGURATION ---
# Command set back to just DAMX as requested
APP_COMMAND="DAMX"
TARGET_KEY_CODE="425"
DEVICE_NAME_FILTER="Acer Wireless Radio Control|Acer WMI hotkeys|AT Translated Set 2 keyboard"

# --- DEVICE DETECTION ---
detect_device() {
EVENT_ID=$(grep -E -A 4 "Name=\"($DEVICE_NAME_FILTER)\"" /proc/bus/input/devices | grep -o 'event[0-9]\+' | head -n 1)
if [ -n "$EVENT_ID" ]; then
echo "/dev/input/$EVENT_ID"
else
return 1
fi

echo "Permission setup complete."
}

# Find keyboard device
DEVICE=$(grep -A 5 -B 5 "keyboard\|Keyboard" /proc/bus/input/devices | grep -m 1 "event" | sed 's/.*event\([0-9]\+\).*/\/dev\/input\/event\1/')
# --- MAIN LOGIC ---

DEVICE=$(detect_device)

# 1. Check if device exists
if [ -z "$DEVICE" ]; then
echo "Error: Could not find keyboard device."
echo "Error: Could not find the Nitro key device."
exit 1
fi

# Check if we're root (sudo)
if [ "$(id -u)" -eq 0 ]; then
# Running as root - perform setup then re-exec as normal user
setup_permissions
echo "Re-launching as normal user..."
exec sudo -u $SUDO_USER "$0"
exit 0
fi

# Check permissions
# 2. Check Permissions & Apply "newgrp" Workaround
if [ ! -r "$DEVICE" ]; then
echo "Error: Cannot read $DEVICE (permission denied)."
echo "Please run this script with sudo to set up permissions:"
echo " sudo $0"
exit 1
echo "Permission denied reading $DEVICE."
echo "Checking groups..."

# Check if user needs to be added to input group
if ! groups | grep -q '\binput\b'; then
echo "Adding user $USER to 'input' group..."
sudo usermod -a -G input $USER

# Check for udev rules
UDEV_RULE="/etc/udev/rules.d/99-input-group.rules"
if [ ! -f "$UDEV_RULE" ]; then
echo 'KERNEL=="event*", SUBSYSTEM=="input", GROUP="input", MODE="0660"' | sudo tee "$UDEV_RULE" > /dev/null
sudo udevadm control --reload-rules
sudo udevadm trigger
fi

echo "Reloading script with new group permissions..."
# This re-runs the script with the new 'input' group active immediately
exec sg input -c "$0 $@"
exit 0
Comment on lines +48 to +50
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exec sg input -c "$0 $@" command on line 49 will re-execute the script with the input group active, but it doesn't preserve the original process tree context. If this script is launched by a process monitor or systemd, the exec call could break the parent-child relationship. Additionally, using $@ without quotes could cause issues with arguments containing spaces. Use "$@" with proper quoting instead.

Suggested change
# This re-runs the script with the new 'input' group active immediately
exec sg input -c "$0 $@"
exit 0
# This re-runs the script with the new 'input' group active immediately,
# preserving argument boundaries and the original process tree context.
CMD=$(printf '%q ' "$0" "$@")
sg input -c "$CMD"
exit $?

Copilot uses AI. Check for mistakes.
fi

# If we are already in the group but still can't read, force udev reload
echo "User is in 'input' group but still cannot read device."
echo "Attempting to force udev reload..."
echo 'KERNEL=="event*", SUBSYSTEM=="input", GROUP="input", MODE="0660"' | sudo tee "/etc/udev/rules.d/99-input-group.rules" > /dev/null
Comment on lines +42 to +56
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The udev rule on line 42 is written to the same file path on line 56, which could create a race condition if multiple instances of this script run simultaneously or if the first write hasn't completed when the second check occurs. Consider adding a lock mechanism or checking if the rule already exists before attempting to write it again.

Copilot uses AI. Check for mistakes.
sudo udevadm control --reload-rules
sudo udevadm trigger
Comment on lines 30 to +58
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The permission handling uses sudo commands (lines 37, 42-44, 56-58) but the script itself doesn't check if it's being run with appropriate privileges. If run without sudo initially, these sudo commands will prompt for password mid-execution, which could be confusing in an automated setup (e.g., KDE autostart). Consider adding an initial check for necessary privileges or documenting that the script should be run with sudo.

Copilot uses AI. Check for mistakes.

# Final check
if [ ! -r "$DEVICE" ]; then
echo "Still cannot read device. A reboot is recommended."
exit 1
fi
fi

# Main functionality
echo "Monitoring keyboard events on $DEVICE"
evtest "$DEVICE" | grep --line-buffered "code 425.*value 1" | while read -r line; do
DAMX &
done
# 3. Monitoring Loop
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The script lacks validation that evtest is installed before attempting to use it on line 70. If evtest is not installed, the script will fail silently or with an unclear error message. Add a check to verify that evtest is available and provide installation instructions if it's missing.

Suggested change
# 3. Monitoring Loop
# 3. Monitoring Loop
# Check that evtest is installed before attempting to use it
if ! command -v evtest >/dev/null 2>&1; then
echo "Error: 'evtest' is not installed or not found in PATH."
echo "Please install 'evtest' using your distribution's package manager, for example:"
echo " Debian/Ubuntu: sudo apt-get install evtest"
echo " Fedora/RHEL: sudo dnf install evtest"
echo " Arch Linux: sudo pacman -S evtest"
exit 1
fi

Copilot uses AI. Check for mistakes.
echo "Listening on $DEVICE for Nitro Key..."

evtest "$DEVICE" | \
grep --line-buffered "code $TARGET_KEY_CODE" | \
while read -r line; do
if echo "$line" | grep -q "value 1"; then
# Check if DAMX is already running (matches process name)
if pgrep -x "DAMX" > /dev/null || pgrep -f "DivAcerManagerMax" > /dev/null; then
echo "DAMX is already running."
else
echo "Launching DAMX..."
nohup "$APP_COMMAND" >/dev/null 2>&1 &
sleep 2
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hardcoded 2-second sleep on line 80 after launching DAMX is arbitrary and could be either too long (wasting time) or too short (if DAMX takes longer to start on slower systems). Consider removing this sleep entirely, or make it configurable. The sleep appears to be intended to prevent immediate re-detection of the key press, but the process check on line 75 should be sufficient for this purpose.

Copilot uses AI. Check for mistakes.
fi
fi
done
Loading
Loading