#!/usr/bin/env bash # State file lives in the user's runtime dir (tmpfs, cleared on logout). # Using XDG_RUNTIME_DIR avoids /tmp collisions on multi-user systems. export STATUS_FILE="$XDG_RUNTIME_DIR/touchpad.status" # Resolve the touchpad's libinput device name dynamically. A previous version # of this script hardcoded one machine's name ("synaptics-tm3053-009") — # `hyprctl keyword device[...]:enabled` silently no-ops when the selector # matches no device, so on any other touchpad (e.g. this Framework 12's # "pixa3854:...-touchpad") the toggle just did nothing. `mice` entries carry # no explicit "type: touchpad" field, but libinput's generated name reliably # includes "touchpad" as a substring. TOUCHPAD_NAME="$(hyprctl devices -j | jq -r '.mice[] | select(.name | test("touchpad"; "i")) | .name' | head -n1)" if [[ -z "$TOUCHPAD_NAME" ]]; then notify-send -u critical "Touchpad toggle" "No touchpad device found" exit 1 fi enable_touchpad() { printf "true" >"$STATUS_FILE" notify-send -u normal "Enabling Touchpad" # hyprlua's config is Lua-generated, not the classic hyprlang parser, so # `hyprctl keyword device[...]:enabled ...` fails outright ("keyword can't # work with non-legacy parsers. Use eval."). hl.device({...}) is the Lua # API's live-reachable equivalent (same hl.* eval bridge eww's workspace # switching uses) — see hypr/hyprland.lua's own hl.device() block. hyprctl eval "hl.device({name='$TOUCHPAD_NAME', enabled=true})" } disable_touchpad() { printf "false" >"$STATUS_FILE" notify-send -u normal "Disabling Touchpad" hyprctl eval "hl.device({name='$TOUCHPAD_NAME', enabled=false})" } # If no status file exists yet, treat as "enabled" (first run after login). if ! [ -f "$STATUS_FILE" ]; then enable_touchpad else # Toggle based on the persisted state: true → disable, false → enable. if [ "$(cat "$STATUS_FILE")" = "true" ]; then disable_touchpad elif [ "$(cat "$STATUS_FILE")" = "false" ]; then enable_touchpad fi fi