Add per-tool settings and gesture customization
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
root=${TOUCHPAD_HOLD_TAP_TEST_ROOT:-}
|
||||
config_file="$root/etc/touchpad-hold-tap.conf"
|
||||
override_file="$root/etc/libinput/plugins/90-touchpad-hold-tap.lua"
|
||||
template_file="$root/usr/lib64/libinput/plugins/90-touchpad-hold-tap.lua"
|
||||
if [[ ! -e $template_file ]]; then
|
||||
template_file="$root/usr/lib/libinput/plugins/90-touchpad-hold-tap.lua"
|
||||
fi
|
||||
|
||||
minimum_anchor_age_ms=100
|
||||
minimum_pause_ms=100
|
||||
minimum_tap_ms=10
|
||||
maximum_tap_ms=150
|
||||
output_event=BTN_MIDDLE
|
||||
|
||||
die()
|
||||
{
|
||||
printf 'touchpad-hold-tap-config: %s\n' "$*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
require_root()
|
||||
{
|
||||
if [[ -z $root && $EUID -ne 0 ]]; then
|
||||
die "this operation must be run as root"
|
||||
fi
|
||||
}
|
||||
|
||||
validate()
|
||||
{
|
||||
[[ $minimum_anchor_age_ms =~ ^[0-9]+$ ]] || die "minimum anchor age must be an integer"
|
||||
[[ $minimum_pause_ms =~ ^[0-9]+$ ]] || die "minimum pause must be an integer"
|
||||
[[ $minimum_tap_ms =~ ^[0-9]+$ ]] || die "minimum tap duration must be an integer"
|
||||
[[ $maximum_tap_ms =~ ^[0-9]+$ ]] || die "maximum tap duration must be an integer"
|
||||
(( minimum_anchor_age_ms <= 2000 )) || die "minimum anchor age must not exceed 2000 ms"
|
||||
(( minimum_pause_ms <= 2000 )) || die "minimum pause must not exceed 2000 ms"
|
||||
(( maximum_tap_ms >= 1 && minimum_tap_ms <= maximum_tap_ms && maximum_tap_ms <= 2000 )) || \
|
||||
die "tap durations must be between 0 and 2000 ms, with a positive maximum and minimum not exceeding maximum"
|
||||
[[ $output_event =~ ^(BTN|KEY)_[A-Z0-9_]+$ ]] || \
|
||||
die "output event must be an evdev BTN_* or KEY_* name"
|
||||
}
|
||||
|
||||
read_config()
|
||||
{
|
||||
if [[ ! -r $config_file ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
while IFS='=' read -r key value; do
|
||||
case $key in
|
||||
MINIMUM_ANCHOR_AGE_MS) minimum_anchor_age_ms=$value ;;
|
||||
MINIMUM_PAUSE_MS) minimum_pause_ms=$value ;;
|
||||
MINIMUM_TAP_MS) minimum_tap_ms=$value ;;
|
||||
MAXIMUM_TAP_MS) maximum_tap_ms=$value ;;
|
||||
OUTPUT_EVENT) output_event=$value ;;
|
||||
''|'#'*) ;;
|
||||
*) die "unknown setting: $key" ;;
|
||||
esac
|
||||
done < "$config_file"
|
||||
validate
|
||||
}
|
||||
|
||||
write_config()
|
||||
{
|
||||
mkdir -p "$(dirname -- "$config_file")"
|
||||
local temporary
|
||||
temporary=$(mktemp "${config_file}.XXXXXX")
|
||||
trap 'rm -f -- "$temporary"' RETURN
|
||||
printf 'MINIMUM_ANCHOR_AGE_MS=%s\nMINIMUM_PAUSE_MS=%s\nMINIMUM_TAP_MS=%s\nMAXIMUM_TAP_MS=%s\nOUTPUT_EVENT=%s\n' \
|
||||
"$minimum_anchor_age_ms" "$minimum_pause_ms" "$minimum_tap_ms" "$maximum_tap_ms" \
|
||||
"$output_event" > "$temporary"
|
||||
chmod 0644 "$temporary"
|
||||
mv -f -- "$temporary" "$config_file"
|
||||
trap - RETURN
|
||||
}
|
||||
|
||||
write_override()
|
||||
{
|
||||
[[ -r $template_file ]] || die "installed plugin was not found"
|
||||
mkdir -p "$(dirname -- "$override_file")"
|
||||
local temporary
|
||||
temporary=$(mktemp "${override_file}.XXXXXX")
|
||||
trap 'rm -f -- "$temporary"' RETURN
|
||||
awk -v age="$minimum_anchor_age_ms" -v pause="$minimum_pause_ms" \
|
||||
-v mintap="$minimum_tap_ms" \
|
||||
-v maxtap="$maximum_tap_ms" \
|
||||
-v output="$output_event" '
|
||||
/^local settings = / {
|
||||
print "local settings = {"
|
||||
print " minimum_anchor_age_ms = " age ","
|
||||
print " minimum_pause_ms = " pause ","
|
||||
print " minimum_tap_ms = " mintap ","
|
||||
print " maximum_tap_ms = " maxtap ","
|
||||
print " output_event = \"" output "\","
|
||||
print "}"
|
||||
replaced = 1
|
||||
next
|
||||
}
|
||||
{ print }
|
||||
END { if (!replaced) exit 1 }
|
||||
' "$template_file" > "$temporary" || die "installed plugin has an unsupported format"
|
||||
chmod 0644 "$temporary"
|
||||
mv -f -- "$temporary" "$override_file"
|
||||
trap - RETURN
|
||||
}
|
||||
|
||||
usage()
|
||||
{
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
touchpad-hold-tap-config show
|
||||
touchpad-hold-tap-config set [--minimum-anchor-age-ms N] [--minimum-pause-ms N] [--minimum-tap-ms N] [--maximum-tap-ms N] [--output-event NAME]
|
||||
touchpad-hold-tap-config reset
|
||||
touchpad-hold-tap-config refresh
|
||||
EOF
|
||||
}
|
||||
|
||||
command=${1:-}
|
||||
case $command in
|
||||
show)
|
||||
[[ $# -eq 1 ]] || die "show takes no arguments"
|
||||
read_config
|
||||
printf 'MINIMUM_ANCHOR_AGE_MS=%s\nMINIMUM_PAUSE_MS=%s\nMINIMUM_TAP_MS=%s\nMAXIMUM_TAP_MS=%s\nOUTPUT_EVENT=%s\n' \
|
||||
"$minimum_anchor_age_ms" "$minimum_pause_ms" "$minimum_tap_ms" "$maximum_tap_ms" \
|
||||
"$output_event"
|
||||
;;
|
||||
set)
|
||||
shift
|
||||
read_config
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--minimum-anchor-age-ms)
|
||||
[[ $# -ge 2 ]] || die "$1 requires a value"
|
||||
minimum_anchor_age_ms=$2
|
||||
shift 2
|
||||
;;
|
||||
--minimum-pause-ms)
|
||||
[[ $# -ge 2 ]] || die "$1 requires a value"
|
||||
minimum_pause_ms=$2
|
||||
shift 2
|
||||
;;
|
||||
--minimum-tap-ms)
|
||||
[[ $# -ge 2 ]] || die "$1 requires a value"
|
||||
minimum_tap_ms=$2
|
||||
shift 2
|
||||
;;
|
||||
--maximum-tap-ms)
|
||||
[[ $# -ge 2 ]] || die "$1 requires a value"
|
||||
maximum_tap_ms=$2
|
||||
shift 2
|
||||
;;
|
||||
--output-event)
|
||||
[[ $# -ge 2 ]] || die "$1 requires a value"
|
||||
output_event=$2
|
||||
shift 2
|
||||
;;
|
||||
*) die "unknown option: $1" ;;
|
||||
esac
|
||||
done
|
||||
require_root
|
||||
validate
|
||||
write_config
|
||||
write_override
|
||||
;;
|
||||
reset)
|
||||
[[ $# -eq 1 ]] || die "reset takes no arguments"
|
||||
require_root
|
||||
rm -f -- "$config_file" "$override_file"
|
||||
;;
|
||||
refresh)
|
||||
[[ $# -eq 1 ]] || die "refresh takes no arguments"
|
||||
require_root
|
||||
if [[ -e $config_file ]]; then
|
||||
read_config
|
||||
write_override
|
||||
else
|
||||
rm -f -- "$override_file"
|
||||
fi
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
usage >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user