Add Linux/Raspberry Pi setup and port the clicker to X11
The clicker had no Linux support at all: pygetwindow has no X11 backend, so _other_activate returned "window management is unsupported" and every step failed before it could click. focus.py now has a third backend that raises the browser with xdotool and reads the focused window's WM_CLASS to verify it came forward - the same activate-then-confirm shape as the macOS and Windows paths. setup-linux.sh mirrors setup-windows.bat with apt instead of winget. Three things are specific to this platform rather than incidental: - Node comes from NodeSource. Pi OS ships one too old for Next 16, and the LTS line is also what better-sqlite3 publishes prebuilt arm64 binaries for. - Python dependencies go in a virtualenv. Pi OS Bookworm enforces PEP 668, so pip into the system interpreter fails with externally-managed-environment. - Autostart uses an XDG ~/.config/autostart entry, the direct analogue of the Windows Startup folder: no sudo, and it runs inside the graphical session, which the clicker needs for DISPLAY. Wayland is called out in four places - the session guard, diagnose.py, the installer and both READMEs - because Pi OS on a Pi 5 defaults to it and the clicker simply cannot work there. Wayland does not let one client synthesise input into another, so this is a switch-to-X11 situation, not a bug to fix. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
3cc632ac40
commit
c5c946d3cc
@@ -12,6 +12,8 @@ OS after each move, so the answer doesn't depend on anything being rendered.
|
||||
Nothing is clicked. The cursor is moved and put back where it started.
|
||||
"""
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import time
|
||||
|
||||
@@ -27,6 +29,19 @@ def check_platform() -> None:
|
||||
line("os", sys.platform)
|
||||
line("python", sys.version.split()[0])
|
||||
|
||||
if sys.platform.startswith("linux"):
|
||||
# The two things that decide whether the clicker can work at all here.
|
||||
session = os.environ.get("XDG_SESSION_TYPE", "unknown")
|
||||
display = os.environ.get("DISPLAY") or "(unset)"
|
||||
line("session type", session)
|
||||
line("DISPLAY", display)
|
||||
line("xdotool", shutil.which("xdotool") or "NOT INSTALLED — sudo apt install -y xdotool")
|
||||
if session == "wayland" or (os.environ.get("WAYLAND_DISPLAY") and not os.environ.get("DISPLAY")):
|
||||
print(" Wayland cannot be automated: xdotool and pyautogui both speak X11,")
|
||||
print(" and Wayland does not let one client drive another. On Raspberry Pi OS:")
|
||||
print(" sudo raspi-config -> Advanced Options -> Wayland -> X11, then reboot.")
|
||||
return
|
||||
|
||||
if sys.platform != "win32":
|
||||
return
|
||||
|
||||
|
||||
Reference in New Issue
Block a user