Your Xbox controller, live in the GNOME top bar.
A small icon that lights up green when a controller connects.
Click it to see the battery, the connection, the model and firmware,
and a picture of the controller that mirrors every button and stick as you play.
A look around · What it shows · Get started · Controllers · How it works · Roadmap
Every picture on this page is Padlight itself, captured in a test session of GNOME Shell 50. The wired controller is real; the Bluetooth ones, their battery readings and the buttons being pressed are simulated.
Note
Padlight is an independent project. It is not affiliated with, endorsed by or connected to Microsoft. Xbox is a trademark of Microsoft.
While the menu is open, the picture follows the controller: buttons light up green, the sticks tilt and the triggers fill as you pull them. Close the menu and Padlight stops reading the controller, unless you turn on Keep the screen awake or Disconnect idle controllers.
On a cable. The Series X|S controller over USB, running on USB power. |
Charging over Bluetooth. The battery comes from UPower, and a Bluetooth controller gets a Disconnect button. |
Running low. At 20% and below, the battery icon turns orange. |
Two at once. Every controller gets its own card, a little smaller so they all fit. |
Nothing connected. A dimmed outline and a hint on how to connect. |
In the top bar. Grey while nothing is connected, green while a controller is. |
| Status at a glance | The icon in the top bar is green while a controller is connected and dimmed while none is. |
| Top-bar options | Two switches in Padlight Settings, both off at first. One puts the battery level beside the icon: with several controllers, the lowest charge, as that controller needs charging first, in orange when it is low. The other hides the icon while no controller is connected, until one connects. While the icon is hidden its menu cannot be opened; Padlight Settings stays in the Extensions app. |
| Battery | The charge, and whether it is charging, for controllers whose driver reports it to UPower. On a cable it reads On USB power. At 20% and below, the battery icon turns orange; the level can be changed in Padlight Settings. |
| Low battery alert | A notification when a controller on batteries reaches the low level, and one more at 10%, with the controller's nickname or name and the charge left. Each comes once, until the battery charges back above the level, and a controller that connects with a low battery gets one straight away. None for a controller on a cable. The alert shows even over a full-screen game; during Do Not Disturb it waits in the notification list. It can be switched off in Padlight Settings. |
| Connection | Wired (USB), Bluetooth or the Xbox Wireless Adapter, and the time the controller connected. |
| Connection notices | A short notification when a controller connects, such as Xbox Wireless Controller connected, or Blue pad connected with a nickname, with Bluetooth · 70% underneath, and one when it leaves, wired, over Bluetooth or through the adapter. Controllers already connected when Padlight starts get none. A controller's newest notice replaces the one before, so a quick reconnect leaves one, and a notice leaves the notification list once it has been seen. It shows even over a full-screen game, and can be switched off in Padlight Settings. |
| Keep the screen awake | A switch in Padlight Settings. While it is on, a button press, or a stick or trigger moved at least a quarter of its way, counts as activity, as a key press does, so the screen does not dim, blank or lock while you play with only a controller. A stick drifting by itself does not count. About ten seconds after the last input, the delays from Settings › Power start counting again. It is off at first because it has Padlight read each connected controller in the background; games still get every input. |
| Idle disconnect | A switch in Padlight Settings, off at first, and a time of 5, 10, 15 or 30 minutes, 15 at first. While the switch is on, a Bluetooth controller with no input for that time is disconnected, as consoles do to save its battery; it stays paired. Input counts as it does for Keep the screen awake, so a stick drifting by itself does not keep a controller connected. It has Padlight read each Bluetooth controller in the background; wired controllers and those on the Xbox adapter are left alone. GNOME turns Padlight off while the screen is locked or blank, so at that moment Padlight disconnects each Bluetooth controller that had no input in the last minute; for the others, the time starts again when you come back. |
| Model and firmware | The model number on the controller's label, such as 1914 for the Series X|S controller, and the firmware version it reports. The driver and the device file are listed underneath. When a controller on Bluetooth runs older firmware than the newest Padlight knows of, the firmware icon turns orange and a line points to the Xbox Accessories app on Windows or an Xbox console, since Linux has no updater for it. That list of versions ships with Padlight, so it can fall behind until the next release, and firmware is not compared over USB yet. |
| In use by | The programs that have the controller open, such as Steam or a game, worked out each time the menu opens. It helps when a game does not see the controller or sees it twice. Only your own programs are listed, and GNOME Shell itself is left out. |
| Live picture | Buttons, sticks, triggers and the d-pad, mirrored as you press them while the menu is open. |
| Stick check | The Sticks tab under the picture shows each stick's exact position, before any dead zone, how far each trigger is pulled, and where each stick rests once you let go. A stick that rests more than 10% of the way from the centre gets a warning: many games ignore about that much, so beyond it a worn stick can move a game by itself (drift). |
| Button checklist | The Buttons tab: press every button, and each one stays lit on the picture once it has responded, with a count such as 12 of 18 and a Reset. The triggers count once pulled at least 90% of the way. Handy for checking a used controller. The count lasts while the controller stays connected, also when the menu closes. |
| Test Vibration | A short rumble to check the motors, on controllers that can vibrate. |
| Find Controller | On a wireless controller that can vibrate: ten short, strong buzzes over six seconds, to find it under a cushion by feel or sound. The button reads Stop Finding meanwhile, and stops it at once. It carries on with the menu closed, and stops if the controller disconnects. |
| Vibration lab | The Vibration tab, on controllers that can vibrate: how hard the strong motor on the left and the weak motor on the right run, from 0 to 100%, and for how long, from 0.1 to 2 seconds, then Play. The settings stay while the controller is connected. Linux drives only these two motors; the motors in the triggers are not part of it. |
| Disconnect | Disconnects a Bluetooth controller from the computer, through bluetoothctl. |
| Several controllers | One card each, made smaller when there is more than one. |
| Nicknames | A name of your own for a controller, such as Blue pad, to tell several apart: press the pencil beside its name on the card, type it and press Enter. The card shows it above the model's name, and the notifications use it. Padlight Settings lists the nicknames, to rename or forget them. A controller is known again by its Bluetooth address, or by its serial number on a cable, but the settings keep only a salted hash of it, never the address or the number. A controller that reports neither cannot keep a nickname, and one used both ways has a nickname for each. |
| Pair a Controller | Finds Xbox controllers that are waiting to pair, then pairs, trusts and connects the one you pick. Hold the pair button on top of the controller until the Xbox button flashes quickly. The search gives up after 30 seconds and stops when the menu closes. With Hide the icon without a controller on, the menu cannot be opened while no controller is connected, so pair the first one from the Bluetooth page of Settings. |
| Bluetooth Settings | Opens the Bluetooth page of Settings, for other devices or when pairing from the menu does not work. |
| Padlight Settings | Opens Padlight's settings window, which the Extensions app also opens. It holds the battery level that counts as low, from 5% to 50%, the switches for the low battery alerts, for connection notices and for disconnecting idle controllers, with its time, the top-bar options, Keep the screen awake, and the nicknames. |
| Your theme | The card takes its colors from the menu around it, so it suits dark and light styles and other shell themes. |
You need GNOME Shell 46 to 50, as on Ubuntu 24.04 LTS to 26.04 LTS or Debian 13; other versions refuse to load Padlight. You also need Python 3, which most distributions include: it runs the small helpers behind the live picture, the vibration test, Find Controller, the In use by line, Keep the screen awake and idle disconnect.
git clone https://github.com/NahuelGenchi/padlight.git
cd padlight
./install.shThen log out and back in, because GNOME Shell only loads a new extension when you log in. The controller icon appears on the right of the top bar.
| To | Run, from the padlight folder |
|---|---|
| Update | git pull, then ./install.sh again, then log out and back in |
| Remove | ./install.sh --uninstall |
| Build the package for extensions.gnome.org | ./install.sh --pack |
What the installer does
install.sh packs src/ with gnome-extensions pack, installs it in ~/.local/share/gnome-shell/extensions/padlight@nahuelgenchi.github.io/ with gnome-extensions install, and switches it on for your user. It needs no administrator rights and changes nothing outside your home folder. Once installed, Padlight also appears in the Extensions app, where you can switch it off and on and open its settings.
Padlight keeps its settings with your other GNOME settings, under /org/gnome/shell/extensions/padlight/. Removing Padlight leaves them in place; dconf reset -f /org/gnome/shell/extensions/padlight/ clears them.
Developed on Ubuntu 26.04 with GNOME Shell 50.1 on Wayland. GNOME Shell 46, 47, 48 and 49 were tried in test sessions inside containers of Ubuntu 24.04, Ubuntu 24.10, Debian 13 and Ubuntu 25.10, with a simulated controller. No other distribution has been tried on a real desktop yet.
| Controller | Connection | Status |
|---|---|---|
| Xbox Series X|S controller (model 1914) | USB cable, xpad driver |
Tried on real hardware |
| Xbox Series X|S controller (model 1914) | Bluetooth, the kernel's own hid-microsoft driver |
Tried on real hardware (#3). The battery shows its charge, but not whether it is charging: over Bluetooth, the reading comes from BlueZ as a percentage only. |
| Xbox Series X|S controller | Bluetooth, xpadneo driver |
Not tried yet (#13) |
| Xbox controllers | Xbox Wireless Adapter | Not tried yet (#14) |
| Other Xbox and Xbox-compatible controllers | USB or Bluetooth | Recognized, not tried on hardware yet; the picture is always the Series X|S controller (#4) |
Padlight recognizes a controller by Microsoft's vendor ID, by an Xbox name, or by the xpad, xpadneo or xone driver. It leaves out the virtual controllers that Steam Input and game streaming create, so each real controller appears once.
flowchart TB
kernel["<b>Linux</b><br/>/dev/input, sysfs"]
services["<b>UPower, BlueZ</b><br/>battery, pairing"]
subgraph shell["GNOME Shell"]
ext["<b>extension.js</b><br/>icon and menu"]
card["<b>controllerCard.js</b><br/>card, live picture"]
end
subgraph helpers["Python helpers"]
monitor["<b>monitor.py</b><br/>buttons, sticks"]
rumble["<b>rumble.py</b><br/>vibration"]
end
kernel --> shell
services --> shell
ext --> card
kernel --> monitor
monitor -->|"while the menu is open"| card
card -->|"Test Vibration"| rumble
Padlight watches /dev/input, so a controller shows up about half a second after it connects, wired or not, and a notification says so; the notification waits up to two more seconds for the battery reading. For each one it reads what the kernel knows: the name, the vendor and product, the firmware version, the driver, and the Bluetooth address or, on a cable, the serial number, by which it finds the controller's nickname. Battery readings come from UPower, and one that reaches the low level sends a notification. Pair a Controller asks BlueZ, the system's Bluetooth service, to search and pair over D-Bus. While the menu is open, monitor.py passes the controller's button and stick changes to the card, which redraws the picture, the stick check or the button checklist; when the menu closes, the helper stops. With Keep the screen awake on, another monitor.py per controller says at most every five seconds that the controller is in use, and Padlight holds GNOME's idle inhibitor, as a video player does, until ten seconds pass without input. Disconnect idle controllers uses the same reader on each Bluetooth controller, and disconnects one through bluetoothctl once it has gone the chosen time without input, or a minute when the screen locks or goes blank, as GNOME turns Padlight off then. Each time the menu opens, inuse.py also looks through your own processes in /proc for the ones that have the controller's device files open, without reading from the controller.
- Games keep every input. The helpers read the controller without taking it over.
- Nothing leaves your computer. No network, no administrator rights, no background service. With the menu closed, Padlight only listens for controllers coming and going, for battery changes and, while Keep the screen awake or Disconnect idle controllers is on, for whether a controller is in use, and finishes a pairing already under way.
| Path | What is in it |
|---|---|
src/extension.js |
The top-bar button: finds controllers, keeps the menu current, starts the helpers |
src/controllers.js |
Finds Xbox controllers in sysfs: connection, model, firmware, driver, device |
src/battery.js |
Battery readings from UPower |
src/batteryAlerts.js |
When a low battery alert is due, and what it says |
src/connectionNotices.js |
Which controllers came and went, and what a connection notice says |
src/nicknames.js |
Which controllers can keep a nickname, and the salted hash it is kept under |
src/notifications.js |
Padlight's notifications in the message tray |
src/firmware.js |
The newest firmware known for each controller, for the update hint |
src/pairing.js |
Pair a Controller: the search and pairing through BlueZ, and its part of the menu |
src/controllerCard.js |
The card: header, the picture, the stick check, the button checklist or the vibration lab and their tabs, tiles, buttons, and the empty state |
src/controllerView.js, src/controllerArt.js |
The live picture, drawn with cairo |
src/controllerCheck.js |
The stick check: the sticks before any dead zone, the triggers, where the sticks rest |
src/buttonCheck.js, src/checklist.js |
The button checklist: the picture with every pressed button lit, and the count |
src/inputMonitor.js |
Runs monitor.py for a card while the menu is open, or for a background reader |
src/controllerActivity.js |
The background readers that say when a controller is in use, for Keep the screen awake and idle disconnect |
src/keepAwake.js |
Keeps the screen awake while a controller is in use |
src/idleDisconnect.js |
Disconnects a Bluetooth controller left idle |
src/monitor.py, src/rumble.py |
The helpers: input changes as they happen, or only whether the controller is in use, and a vibration of a set strength and length, or Find Controller's bursts |
src/vibrationLab.js |
The vibration lab: the two motors' strengths, the length and Play |
src/inuse.py |
The helper that finds which programs have a controller open |
src/stylesheet.css |
The card's look on dark and light menus |
src/shellVersions.js |
What differs between GNOME Shell 46 and 50 |
src/prefs.js, src/schemas/ |
The settings window, and the settings it keeps |
src/icons/ |
Top-bar icon, USB icon, the controller artwork and its glow |
install.sh |
Install, update, pack or remove |
tests/ |
The checks every PR runs, all through tests/run.sh: detection, battery readings and alerts, connection notices, nicknames, idle disconnect, the background readers and the helpers, on made-up data |
Padlight is young. What is on this page works today. Next on the list:
- An icon of its own for the top bar, instead of the Xbox logo (#5).
- The xpadneo driver and the Xbox Wireless Adapter, tried on real hardware (#13, #14).
- Pictures of other controllers, such as the Elite Series 2 and the Xbox One controller (#4).
- extensions.gnome.org, to install it with one click (#6).
- Translations, starting with Spanish (#32).
| Milestone | Outcome |
|---|---|
| M0 — Project foundation | Repository, documentation and the way work is tracked |
| M1 — Indicator and live view | The top-bar icon, the card and the live picture, and their fixes |
| M2 — More controllers | Other Xbox models and their pictures, Bluetooth and the adapter on real hardware |
| M3 — Release | Packaging, the extensions.gnome.org listing and versioned releases |
| M4 — Settings and alerts | A settings window, notifications, top-bar options, keeping the screen awake, nicknames and idle disconnect |
| M5 — Controller tools | Checks for the sticks, triggers, buttons and vibration; finding a controller, the apps using it, firmware hints and pairing |
Every change, however small, follows the same trail:
flowchart TB
issue["<b>Issue</b><br/>goal, scope, milestone"] --> branch["<b>Branch</b><br/>type/issue-slug"] --> pr["<b>Pull request</b><br/>closes the issue,<br/>same milestone"] --> main["<b>main</b>"]
Found a bug or have an idea? Open a work item. Before sending code, read CONTRIBUTING.md and docs/TRACKING.md; agents start with AGENTS.md.
- The controller picture is artwork by Nahuel Genchi.
- The top-bar icon is the Xbox logo, a trademark of Microsoft, used to name the controllers Padlight works with. An icon of Padlight's own is planned (#5).
- The Padlight logo was drawn for this project.
Padlight is free software under the GNU General Public License, version 2 or any later version (GPL-2.0-or-later). You may use, share and change it; if you share a changed version, share its source under the same terms. The license covers the code, the controller artwork and the Padlight logo. It does not cover the Xbox logo in src/icons/xbox-symbolic.svg, which remains Microsoft's trademark.