Right now I am trying to remap the power button to give me more flexibility in how I control my Switch
First things first, install Zenity and Yad, we frankly don’t need both but Zenity will be the fallback if Yad doesn’t wanna work
sudo apt install zenity -y
sudo apt install yad -y
There are a couple ways to do this, like hard coding the input name for the power key, but here we have a small helper that should find it every time. It checks for multiple event names and then also checks if they have access to the KEY_POWER function.
sudo tee /usr/local/bin/find-powerkey >/dev/null <<'EOF'
#!/bin/sh
# Find the /dev/input/eventN that handles the POWER key.
# Strategy:
# 1) Prefer devices with names like max77620_onoff / gpio-keys / Power Button
# 2) Verify the device actually supports KEY_POWER via evtest --query
# 3) If none match by name, fall back to any event* that supports KEY_POWER
set -eu
PREF_RE='(max77620_onoff|gpio-keys|Power Button|power|POWER)'
DEVICES_FILE=/proc/bus/input/devices
# Extract candidate event nodes with names we like
candidates="$(awk -v RS= -v FS='\\n' -v re="$PREF_RE" '
{
name_match=0; event=""
for (i=1; i<=NF; i++){
if ($i ~ /^N: Name=/ && $i ~ re) name_match=1
if ($i ~ /^H: Handlers=/){
if (match($i, /(event[0-9]+)/)) event="/dev/input/" substr($i, RSTART, RLENGTH)
}
}
if (name_match && event!="") print event
}
' "$DEVICES_FILE")"
# Helper: does a node support KEY_POWER?
supports_power() {
/usr/bin/evtest --query "$1" EV_KEY KEY_POWER >/dev/null 2>&1
}
# 1) Try preferred names first
for n in $candidates; do
if supports_power "$n"; then
echo "$n"
exit 0
fi
done
# 2) Fallback: any event* that supports KEY_POWER
for n in /dev/input/event*; do
[ -e "$n" ] || continue
if supports_power "$n"; then
echo "$n"
exit 0
fi
done
# Not found -> exit non-zero so caller can fall back
exit 1
EOF
sudo chmod +x /usr/local/bin/find-powerkey
You can test this yourself to see if it returns the correct event number. First run sudo evtest and check the events to see which one is your power key.
Then, after running the above command, run /usr/local/bin/find-powerkey
It should return something like
/dev/input/event0
Next, we will install a script that listens for our power key, this should pull up a zenity menu upon pressing our power key that gives us multiple options including:
sudo tee /usr/local/bin/powerkey-listener.sh >/dev/null <<'EOF'
#!/bin/bash
set -euo pipefail
LOG_TAG="powerkey"
log(){ logger -t "$LOG_TAG" "$*"; echo "$LOG_TAG: $*"; }
DEV="$(/usr/local/bin/find-powerkey 2>/dev/null || true)"
[ -n "$DEV" ] || DEV="/dev/input/event0"
export DISPLAY=:0
export XAUTHORITY=/home/ozswitchserver/.Xauthority
export XDG_RUNTIME_DIR=/run/user/1000
# Touch-friendly power menu: prefer yad, fallback to zenity
show_menu() {
# Sized for 1280×720
local W=1024 H=640
if command -v yad >/dev/null 2>&1; then
set +H # ensure '!' in labels won't trigger history expansion
# Big label + a thin divider line (second line). Swap to underscores if you prefer.
local DIV="────────────" # or: "___________"
local L_SCREEN L_SUSPEND L_SHUTDOWN L_REBOOT
L_SCREEN=$'<span size="xx-large" weight="bold">Screen Off</span>\\n<span size="small" weight="light">'"$DIV"$'</span>'
L_SUSPEND=$'<span size="xx-large" weight="bold">Suspend</span>\\n<span size="small" weight="light">'"$DIV"$'</span>'
L_SHUTDOWN=$'<span size="xx-large" weight="bold">Shutdown</span>\\n<span size="small" weight="light">'"$DIV"$'</span>'
L_REBOOT=$'<span size="xx-large" weight="bold">Reboot</span>\\n<span size="small" weight="light">'"$DIV"$'</span>'
local -a YAD_OPT_COMMON=(
--center --on-top --undecorated --skip-taskbar
--geometry="${W}x${H}"
--title="Power Options"
--borders=48
--opacity=80
--icon-size=64
)
yad "${YAD_OPT_COMMON[@]}" \\
--form \\
--columns=2 \\
--align=center \\
--buttons-layout=center \\
--button="Cancel:1" \\
\\
--field="${L_SCREEN}!display-brightness-off:BTN" "bash -lc '/usr/local/bin/screenctl off; kill -TERM \\$YAD_PID'" \\
--field="${L_SUSPEND}!system-suspend:BTN" "bash -lc 'systemctl suspend; kill -TERM \\$YAD_PID'" \\
--field="${L_SHUTDOWN}!system-shutdown:BTN" "bash -lc 'systemctl poweroff; kill -TERM \\$YAD_PID'" \\
--field="${L_REBOOT}!system-reboot:BTN" "bash -lc 'systemctl reboot; kill -TERM \\$YAD_PID'"
return $?
fi
# Fallback: Zenity
local choice
choice=$(/usr/bin/zenity --list --title="Power Options" \\
--column="Action" \\
"Turn screen off" "Suspend" "Shutdown" "Reboot" \\
--width="$W" --height="$H") || return 1
case "$choice" in
"Turn screen off") /usr/local/bin/screenctl off ;;
"Suspend") /bin/systemctl suspend ;;
"Shutdown") /bin/systemctl poweroff ;;
"Reboot") /bin/systemctl reboot ;;
esac
}
log "Monitoring power key device (persistent grab): $DEV"
while true; do
/usr/bin/evtest --grab "$DEV" 2>/dev/null | while read -r line; do
if [[ ( "$line" == *"KEY_POWER"* || "$line" == *"KEY_SLEEP"* ) && "$line" == *"value 1"* ]]; then
log "Power key pressed → opening menu"
if ! /usr/local/bin/screenctl status | grep -q "State: ON"; then
/usr/local/bin/screenctl on || log "WARN: screenctl on failed"
sleep 0.15
fi
show_menu || log "Menu canceled or closed"
fi
done
log "evtest loop ended → restarting listener"
sleep 0.5
done
EOF
sudo chmod +x /usr/local/bin/powerkey-listener.sh
systemctl --user daemon-reload
systemctl --user restart powerkey-listener.service
While this script works, there are other events that listen to KEY_POWER and grab it first, initiating their own commands. Checking systemd-logind we see that the powerkey is set to poweroff, not suspend.