#!/bin/sh # Clawdie operator USB X11 touchpad guard. # # Some XFCE/XInput setups can leave the built-in ASUS pointer pair disabled # even though Xorg/libinput attached it correctly. On the affected Ryzen ASUS # laptop the internal HID-over-I2C device shows up as both "... TouchPad" and # sibling "... Mouse". Run as the live user inside the X session and # re-enable the affected internal devices after xfsettingsd has had a chance # to apply user settings. LOG="${HOME:-/tmp}/.clawdie-touchpad-guard.log" log() { printf '%s %s\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" "$*" >>"$LOG" 2>/dev/null || true } prop_id() { _needle="$1" awk -F '[()]' -v needle="$_needle" 'index($0, needle) { print $2; exit }' } set_prop_values() { _id="$1" _prop="$2" shift 2 [ -n "$_prop" ] || return 0 xinput set-prop "$_id" "$_prop" "$@" >/dev/null 2>&1 || true } set_send_events_enabled() { _id="$1" _props="$2" _prop="$(printf '%s\n' "$_props" | prop_id 'libinput Send Events Mode Enabled (')" [ -n "$_prop" ] || return 0 # libinput exposes "disabled" modes here; all-zero means "send events". # The tuple width varies, so try the common shapes in descending order. xinput set-prop "$_id" "$_prop" 0 0 0 >/dev/null 2>&1 \ || xinput set-prop "$_id" "$_prop" 0 0 >/dev/null 2>&1 \ || xinput set-prop "$_id" "$_prop" 0 >/dev/null 2>&1 \ || true } is_target_pointer_device() { _name="$1" _props="$2" printf '%s\n' "$_props" | grep -qi 'touchpad' && return 0 case "$_name" in ASUE*TouchPad|ASUE*Mouse) return 0 ;; esac return 1 } enable_internal_pointers_once() { if ! command -v xinput >/dev/null 2>&1; then log "xinput missing; cannot check built-in pointers" return 0 fi _found=0 for _id in $(xinput list --id-only 2>/dev/null); do _props="$(xinput list-props "$_id" 2>/dev/null || true)" _name="$(printf '%s\n' "$_props" | sed -n "s/^Device '\(.*\)':/\1/p" | head -n 1)" [ -n "$_name" ] || _name="id=$_id" is_target_pointer_device "$_name" "$_props" || continue _found=1 xinput enable "$_id" >/dev/null 2>&1 || true _tap_prop="$(printf '%s\n' "$_props" | prop_id 'libinput Tapping Enabled (')" set_prop_values "$_id" "$_tap_prop" 1 _dwt_prop="$(printf '%s\n' "$_props" | prop_id 'libinput Disable While Typing Enabled (')" set_prop_values "$_id" "$_dwt_prop" 0 set_send_events_enabled "$_id" "$_props" _updated_props="$(xinput list-props "$_id" 2>/dev/null || true)" _enabled="$(printf '%s\n' "$_updated_props" | awk -F: '/Device Enabled/ { gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2; exit }')" _send_events="$(printf '%s\n' "$_updated_props" | awk -F: '/libinput Send Events Mode Enabled/ { gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2; exit }')" _dwt_state="$(printf '%s\n' "$_updated_props" | awk -F: '/libinput Disable While Typing Enabled/ { gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2; exit }')" log "pointer ${_name}: Device Enabled=${_enabled:-unknown} SendEvents=${_send_events:-unknown} DWT=${_dwt_state:-unknown} tapping_prop=${_tap_prop:-none}" done if [ "$_found" -eq 0 ]; then log "no target internal ASUS pointer device found" fi } # Run multiple times because xfsettingsd and saved-session restoration can # apply pointer settings after the session wrapper starts. for _delay in 1 5 15 30; do sleep "$_delay" enable_internal_pointers_once done