Open Steam Big Picture automatically the moment you turn an Xbox controller on.
There is no built-in Steam setting for this. Valve's "Guide button focuses Steam" trick needs Steam already running and a manual double-tap of the Xbox button. This is a tiny background watcher that does it for real: it polls XInput, so it sees the pad whether it connects over Bluetooth, the Xbox wireless dongle, or USB, and fires Steam's Big Picture the instant a new controller appears.
Windows only. It must run on native Windows Python — XInput is a host API and is invisible from inside WSL.
- Windows 10 or 11
- Python for Windows 3.8+, installed with "Add python.exe to PATH" checked
- Steam installed (Steam registers the
steam://protocol handler)
No third-party packages — the watcher uses only the Python standard library.
python controller_bigpicture.pyLeave that running and turn your controller on. Big Picture should open. Run it with
python (not pythonw) for this first test so you can see any error in the console.
Press Ctrl+C to stop.
Install a Startup entry that launches the watcher with pythonw.exe (no console
window):
powershell -ExecutionPolicy Bypass -File .\install.ps1That drops a shortcut in your Startup folder, so it starts automatically every time you sign in. The installer also prints a command to start it immediately without rebooting.
To also wake the monitor on connect, or log to a file, pass the matching switches:
powershell -ExecutionPolicy Bypass -File .\install.ps1 -Wake # wake display too
powershell -ExecutionPolicy Bypass -File .\install.ps1 -Wake -Log # wake + logTo remove it:
powershell -ExecutionPolicy Bypass -File .\uninstall.ps1| Flag | Effect |
|---|---|
| (none) | Watch for a new connection. A pad that is already on when the watcher starts is ignored, so rebooting with the controller on won't relaunch Big Picture. |
--launch-now |
Also fire if a controller is already connected at start. Use this if you usually boot with the pad already on and want Big Picture then too. |
--wake |
On connect, also wake the monitor and dismiss the screensaver before opening Big Picture. Cannot bypass a password/PIN lock — see Waking the screen below. |
--log |
Write a timestamped log to %LOCALAPPDATA%\controller-bigpicture\watcher.log. Handy for confirming the silent pythonw instance is alive. |
With --wake, the watcher also turns the monitor back on and dismisses a running
screensaver the moment the controller connects, so a couch PC goes from dark screen
straight to Big Picture.
The important limit: no user-space script can get past the Windows password /
PIN lock screen — that's a deliberate security boundary, not something to work
around. --wake only helps when the session is unlocked underneath (monitor asleep
or screensaver running). If the PC is genuinely locked, the most it does is light up
the monitor showing the lock screen; you still sign in.
To make a living-room PC go all the way to the desktop hands-free, change the Windows setting rather than the script:
- Settings → Accounts → Sign-in options → "If you've been away, when should Windows require you to sign in again?" → Never.
- If a screensaver is set, untick "On resume, display logon screen" (Screen Saver Settings).
- For a secure auto-unlock that does satisfy the lock screen, use Windows Hello (face / fingerprint) — a controller can't supply that, but Hello can.
Storing your password to auto-type it is not supported here: it's a real security risk and defeats the point of the lock.
XInput exposes up to four controller slots. Once a second the watcher asks XInput
whether any slot is connected. On a transition from "none" to "connected" it calls
os.startfile("steam://open/bigpicture"), which hands off to Steam's protocol
handler (starting Steam first if it isn't running).
- Nothing happens when I run it. Make sure you're using native Windows Python,
not WSL. From PowerShell,
python -c "import os; print(os.name)"must printnt. No XInput DLL found. Very old Windows only.xinput1_3ships with the DirectX End-User Runtime; install that and retry.- Big Picture doesn't open but there's no error. Confirm the URL works at all:
paste
steam://open/bigpictureinto Win+R and press Enter. If that does nothing, the issue is Steam's protocol handler, not this script. - It opens Big Picture on every reboot. You're probably passing
--launch-now, or your controller reports connected at login. Drop the flag — the default already ignores an already-on pad. --wakelights the monitor but I still see the lock screen. Expected when the session requires a password/PIN. See Waking the screen above.
iOS can't run a background watcher and has no Big Picture of its own, so the Windows behaviour doesn't port directly. Two setups do work — full steps in ios/README.md:
-
Controller connects to your iPhone → open a game app (e.g. Steam Link to stream your PC). A Shortcuts Bluetooth automation, no code required.
-
iPhone as a remote that opens Big Picture on the PC, using the included
bigpicture_server.py:python bigpicture_server.py # http://<pc-ip>:8765/bigpicture python bigpicture_server.py --token mysecret # require ?token=mysecret
An iPhone Home Screen shortcut then hits that URL over your LAN.
- Steam Deck / SteamOS already boots into Gamepad UI; you don't need this.
- macOS / Linux desktop use a different controller API (IOKit / evdev), so the detection would need rewriting. Open an issue and say which.
MIT — see LICENSE.