Skip to content

Instantly share code, notes, and snippets.

@evanesoteric
Last active June 1, 2025 16:46
Show Gist options
  • Select an option

  • Save evanesoteric/1cce652264a43a55e29ec7dc94a2a972 to your computer and use it in GitHub Desktop.

Select an option

Save evanesoteric/1cce652264a43a55e29ec7dc94a2a972 to your computer and use it in GitHub Desktop.
Autofocus the HorizonXI game window when gamepad input is detected. A Final Fantasy XI (FFXI) gaming script.
#!/usr/bin/env python3
import evdev
import time
import subprocess
import sys
import threading
# ====================================================================
# CONFIGURATION - MODIFY THIS SECTION FOR YOUR SETUP
# ====================================================================
USERNAME = "evanesoteric" # Change this to your username (will be auto-capitalized)
# ====================================================================
class GamepadAutoFocus:
def __init__(self, cooldown_seconds=10):
self.cooldown_seconds = cooldown_seconds
self.is_monitoring = True
self.last_focus_time = 0
self.device = None
self.target_window = None
self.target_window_name = USERNAME.capitalize() # Capitalize the username
print(f"Looking for window named: '{self.target_window_name}'")
print(f"(Based on username: '{USERNAME}')\n")
def find_gamesir(self):
devices = [evdev.InputDevice(path) for path in evdev.list_devices()]
for device in devices:
if "GameSir G7 SE" in device.name:
return device.path
return None
def get_target_window(self):
"""Get the target window ID based on the configured username"""
try:
# Get horizon-loader PID
result = subprocess.run(['pgrep', '-f', 'horizon-loader'],
capture_output=True, text=True)
if result.returncode != 0:
return None
horizon_pid = result.stdout.strip()
print(f"horizon-loader PID: {horizon_pid}")
# Get all windows for this PID
result = subprocess.run(['xdotool', 'search', '--pid', horizon_pid],
capture_output=True, text=True)
if result.returncode != 0:
return None
window_ids = result.stdout.strip().split('\n')
print(f"Found {len(window_ids)} windows for horizon-loader:")
target_window = None
for i, window_id in enumerate(window_ids, 1):
try:
name_result = subprocess.run(['xdotool', 'getwindowname', window_id],
capture_output=True, text=True)
window_name = name_result.stdout.strip() if name_result.returncode == 0 else "No name"
print(f" Window {i}: {window_id} = '{window_name}'")
if window_name == self.target_window_name:
target_window = window_id
print(f" ★ This is the target game window!")
except Exception as e:
print(f" Window {i}: {window_id} = Error: {e}")
return target_window
except Exception as e:
print(f"Error: {e}")
return None
def is_window_focused(self):
"""Check if the target window is currently focused"""
try:
result = subprocess.run(['xdotool', 'getactivewindow'],
capture_output=True, text=True)
if result.returncode == 0:
active_window = result.stdout.strip()
return active_window == self.target_window
except:
pass
return False
def focus_window(self):
"""Focus the target window and start cooldown"""
try:
subprocess.run(['xdotool', 'windowfocus', self.target_window],
stderr=subprocess.DEVNULL)
current_time = time.time()
self.last_focus_time = current_time
print(f"🎮 Focused {self.target_window_name} window - entering {self.cooldown_seconds}s cooldown")
# Start cooldown timer in a separate thread
threading.Thread(target=self.cooldown_timer, daemon=True).start()
# Stop monitoring temporarily
self.is_monitoring = False
except Exception as e:
print(f"Error focusing window: {e}")
def cooldown_timer(self):
"""Handle the cooldown period"""
time.sleep(self.cooldown_seconds)
self.is_monitoring = True
print(f"✅ Cooldown ended - monitoring gamepad again")
def monitor_gamepad(self):
"""Monitor gamepad input with smart focusing"""
print(f"Monitoring gamepad - will focus game window when you use it")
print(f"After focusing, will wait {self.cooldown_seconds} seconds before monitoring again")
print("Press Ctrl+C to stop\n")
event_count = 0
significant_input_threshold = 3 # Require multiple inputs to avoid accidental triggers
try:
for event in self.device.read_loop():
# Only process events when monitoring is enabled
if not self.is_monitoring:
continue
# Only respond to button presses and significant stick movements
if event.type == evdev.ecodes.EV_KEY and event.value == 1:
# Button press
event_count += 1
elif event.type == evdev.ecodes.EV_ABS and abs(event.value) > 10000:
# Significant analog stick/trigger movement
event_count += 1
else:
continue
# Check if we have enough significant input to warrant focusing
if event_count >= significant_input_threshold:
# Check if window is already focused to avoid unnecessary focusing
if not self.is_window_focused():
self.focus_window()
else:
print("🎯 Game window already focused - entering cooldown anyway")
self.is_monitoring = False
threading.Thread(target=self.cooldown_timer, daemon=True).start()
event_count = 0 # Reset counter
# Reset counter if no significant input for a while
current_time = time.time()
if hasattr(self, '_last_input_time'):
if current_time - self._last_input_time > 2.0: # 2 second timeout
event_count = 0
self._last_input_time = current_time
except KeyboardInterrupt:
print("\nStopped monitoring gamepad")
def main():
# Parse command line arguments for cooldown time
cooldown_time = 10 # Default 10 seconds
if len(sys.argv) > 1:
try:
cooldown_time = int(sys.argv[1])
print(f"Using custom cooldown time: {cooldown_time} seconds")
except ValueError:
print(f"Invalid cooldown time '{sys.argv[1]}', using default: 10 seconds")
autofocus = GamepadAutoFocus(cooldown_seconds=cooldown_time)
# Find gamepad
device_path = autofocus.find_gamesir()
if not device_path:
print("GameSir G7 SE not found")
sys.exit(1)
# Find the target window
autofocus.target_window = autofocus.get_target_window()
if not autofocus.target_window:
print(f"Could not find window named '{autofocus.target_window_name}'!")
print("Make sure:")
print(f"1. The game is running")
print(f"2. The USERNAME variable is set correctly at the top of this script")
print(f"3. Your actual window name is '{autofocus.target_window_name}' (case-sensitive)")
return
print(f"\nUsing target window: {autofocus.target_window} ('{autofocus.target_window_name}')")
# Open device
try:
autofocus.device = evdev.InputDevice(device_path)
print(f"Connected to: {autofocus.device.name}")
except Exception as e:
print(f"Error opening gamepad: {e}")
return
# Start monitoring
try:
autofocus.monitor_gamepad()
except Exception as e:
print(f"Error: {e}")
finally:
if autofocus.device:
autofocus.device.close()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment