181 lines
4.5 KiB
Bash
181 lines
4.5 KiB
Bash
#!/bin/bash
|
|
|
|
debug() {
|
|
# DEBUG comes from the environment
|
|
if (( DEBUG )); then
|
|
printf '%s\n' "$@" >&2
|
|
fi
|
|
}
|
|
|
|
is_enabled() {
|
|
local id="${1?}"
|
|
enabled=$(
|
|
xinput list-props "$id" |
|
|
grep '\bDevice Enabled\b' | sed 's/.*\(.\)$/\1/'
|
|
)
|
|
# xinput returns 0 for disabled and 1 for enabled, so we invert since we
|
|
# pass on 0
|
|
return "$(( !enabled ))"
|
|
}
|
|
|
|
should_disable() {
|
|
local id="${1?}"
|
|
local force_enable="${2?}"
|
|
local force_disable="${3?}"
|
|
|
|
if (( force_enable )) && (( force_disable )); then
|
|
echo '-d and -e make no sense together' >&2
|
|
exit 3
|
|
fi
|
|
|
|
if (( force_enable )); then
|
|
return 1
|
|
elif (( force_disable )); then
|
|
return 0
|
|
elif is_enabled "$id"; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
get_id_for_device_name() {
|
|
local name="${1?}"
|
|
xinput list "$name" | sed -n 's/.*id=\([0-9]\+\).*/\1/p'
|
|
}
|
|
|
|
show_help() {
|
|
cat << EOF
|
|
Usage: ${0##*/} [-n]
|
|
|
|
Enable and disable xinput devices.
|
|
|
|
-d disable only, do not toggle
|
|
-e enable only, do not toggle
|
|
-h show this help page
|
|
-i XID only operate on device with xinput id XID
|
|
-r REGEX only operate on devices matching name REGEX
|
|
-n show results using notify-send in addition to stdout
|
|
-p print what we would do, but don't actually do it
|
|
-t SECONDS revert enable/disable after SECONDS seconds, ie. if you were
|
|
enabling, after SECONDS seconds it will be disabled again.
|
|
SECONDS must be an integer greater than 0
|
|
EOF
|
|
}
|
|
|
|
act_on_device() {
|
|
local print="${1?}"
|
|
local notify="${2?}"
|
|
local timeout="${3?}"
|
|
local xinput_action="${4?}"
|
|
local our_next_flag="${5?}"
|
|
local id="${6?}"
|
|
|
|
if (( print )); then
|
|
echo "Would $xinput_action device with id $id"
|
|
else
|
|
xinput -"$xinput_action" "$id"
|
|
|
|
if (( notify )); then
|
|
notify-send "${xinput_action^}d device with id $id"
|
|
fi
|
|
|
|
if (( timeout )); then
|
|
debug "Added timeout $timeout"
|
|
{
|
|
sleep "$timeout"
|
|
# TODO: Make args_without_timeour_or_force non-global (sigh,
|
|
# shell makes this difficult due to pass by value)
|
|
"$0" "${args_without_timeout_or_force[@]}" \
|
|
"$our_next_flag" -i "$id"
|
|
} &
|
|
fi
|
|
fi
|
|
}
|
|
|
|
notify=0
|
|
force_enable=0
|
|
force_disable=0
|
|
timeout=0
|
|
print=0
|
|
only_xid=0
|
|
input_ids=()
|
|
args_without_timeout_or_force=()
|
|
|
|
while getopts dehi:npr:t: opt; do
|
|
# We need to get a list of args without timeout/force for when we execute
|
|
# timeout reversions. This is a blacklist of things we should not put in
|
|
# the array, since they force enable/disable/name or do the timeout itself.
|
|
case "$opt" in
|
|
d|e|t|r)
|
|
: # Blacklisted
|
|
;;
|
|
*)
|
|
args_without_timeout_or_force+=( -"$opt" )
|
|
if [[ $OPTARG ]]; then
|
|
args_without_timeout_or_force+=( "$OPTARG" )
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
case "$opt" in
|
|
'd') force_disable=1 ;;
|
|
'e') force_enable=1 ;;
|
|
'n') notify=1 ;;
|
|
'i') only_xid="$OPTARG" ;;
|
|
'h')
|
|
show_help
|
|
exit 0
|
|
;;
|
|
'p') print=1 ;;
|
|
'r') regex="$OPTARG" ;;
|
|
't') timeout="$OPTARG" ;;
|
|
'?')
|
|
show_help >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if (( only_xid )) && [[ "$regex" ]]; then
|
|
echo '-r and -i cannot be currently used together' >&2
|
|
exit 4
|
|
elif ! (( only_xid )) && ! [[ "$regex" ]]; then
|
|
echo 'either -r or -i must be passed to filter devices' >&2
|
|
exit 5
|
|
fi
|
|
|
|
if (( only_xid )); then
|
|
input_ids=( "$only_xid" )
|
|
else
|
|
mapfile -t matched_device_names < <(
|
|
xinput list |
|
|
sed -n 's/.*↳ \(.\+\)id=.*\[slave.*/\1/p' |
|
|
sed 's/[\t ]*$//' |
|
|
grep -i -- "$regex"
|
|
)
|
|
|
|
debug 'Matched device names:' "${matched_device_names[@]}"
|
|
|
|
for name in "${matched_device_names[@]}"; do
|
|
input_ids+=( "$(get_id_for_device_name "$name")" )
|
|
done
|
|
fi
|
|
|
|
if (( "${#input_ids[@]}" == 0 )); then
|
|
msg='No matching devices found'
|
|
echo "$msg" >&2
|
|
(( notify )) && notify-send "$msg"
|
|
exit 2
|
|
fi
|
|
|
|
for id in "${input_ids[@]}"; do
|
|
if should_disable "$id" "$force_enable" "$force_disable"; then
|
|
act_on_device "$print" "$notify" "$timeout" disable -e "$id"
|
|
else
|
|
act_on_device "$print" "$notify" "$timeout" enable -d "$id"
|
|
fi
|
|
done
|
|
|
|
# We may have queued some timeout reversion jobs
|
|
wait
|