#!/bin/bash # Autoclicker script for Sway # Clicks continuously with random delays and periodic breaks # Press ESC to stop # Requires ydotool and ydotoold daemon running # Configuration MIN_DELAY=51 # Minimum delay in milliseconds MAX_DELAY=689 # Maximum delay in milliseconds MIN_CLICKS_BEFORE_BREAK=50 # Minimum clicks before break MAX_CLICKS_BEFORE_BREAK=300 # Maximum clicks before break MIN_BREAK=5 # Minimum break duration in seconds MAX_BREAK=10 # Maximum break duration in seconds STATE_FILE="/tmp/autoclicker_running" LOCK_FILE="/tmp/autoclicker_lock" # Check if ydotool is available if ! command -v ydotool &> /dev/null; then echo "Error: ydotool is not installed. Install it with: sudo pacman -S ydotool" exit 1 fi # Check if bc is available (needed for random delay calculation) if ! command -v bc &> /dev/null; then echo "Error: bc is not installed. Install it with: sudo pacman -S bc" exit 1 fi # Check if script is already running (prevent multiple instances) if [ -f "$LOCK_FILE" ]; then echo "Autoclicker is already running!" echo "Press ESC to stop it." exit 0 fi # Create lock file echo $$ > "$LOCK_FILE" # Clean up lock file on exit cleanup() { rm -f "$LOCK_FILE" rm -f "$STATE_FILE" echo "" echo "Autoclicker stopped." } trap cleanup EXIT INT TERM # Check if ydotoold daemon is running if ! pgrep -x "ydotoold" > /dev/null; then echo "Starting ydotoold daemon..." sudo ydotoold & sleep 1 fi # Create state file to indicate running echo "running" > "$STATE_FILE" # Function to generate random delay in seconds get_random_delay() { local min=$1 local max=$2 local range=$((max - min)) local random_ms=$((min + RANDOM % (range + 1))) echo "scale=3; $random_ms / 1000" | bc } # Function to generate random number of clicks before break get_random_clicks() { local min=$1 local max=$2 local range=$((max - min)) echo $((min + RANDOM % (range + 1))) } # Function to check if ESC key was pressed (by checking if state file was removed) check_exit() { if [ ! -f "$STATE_FILE" ]; then echo "Exit signal received!" exit 0 fi } echo "==========================================" echo "Autoclicker started!" echo "==========================================" echo "Configuration:" echo " - Click delay: ${MIN_DELAY}-${MAX_DELAY}ms" echo " - Break every: ${MIN_CLICKS_BEFORE_BREAK}-${MAX_CLICKS_BEFORE_BREAK} clicks (random)" echo " - Break duration: ${MIN_BREAK}-${MAX_BREAK}s" echo "" echo "Press ESC or run: rm $STATE_FILE" echo "==========================================" echo "" click_count=0 total_clicks=0 clicks_before_break=$(get_random_clicks $MIN_CLICKS_BEFORE_BREAK $MAX_CLICKS_BEFORE_BREAK) echo "Next break will be after $clicks_before_break clicks" echo "" while true; do check_exit # Generate random delay before this click delay=$(get_random_delay $MIN_DELAY $MAX_DELAY) # Perform click (suppress ydotool output) ydotool click 0xC0 2>/dev/null click_count=$((click_count + 1)) total_clicks=$((total_clicks + 1)) # Convert delay to milliseconds for display delay_ms=$(echo "$delay * 1000" | bc | cut -d'.' -f1) # Show each click with its delay echo "Click #$total_clicks (delay: ${delay_ms}ms, next break in $((clicks_before_break - click_count)) clicks)" # Check if it's time for a break if [ $click_count -ge $clicks_before_break ]; then break_duration=$(get_random_delay $((MIN_BREAK * 1000)) $((MAX_BREAK * 1000))) echo "" echo "[Break] Completed $clicks_before_break clicks (total: $total_clicks). Taking a break for ${break_duration}s..." sleep "$break_duration" click_count=0 # Generate new random click count for next cycle clicks_before_break=$(get_random_clicks $MIN_CLICKS_BEFORE_BREAK $MAX_CLICKS_BEFORE_BREAK) echo "[Resumed] Next break will be after $clicks_before_break clicks" echo "" else # Wait the random delay before next click sleep "$delay" fi done