#!/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
