# bluetooth The adapter, its devices, and pairing, in one module. The tile names the connected device, or a count when several, `No devices` when the adapter is on and idle, `Off` when it is down. The page carries the adapter power switch, a visible toggle, a scan toggle, then the connected devices, the paired ones, and anything found while scanning. A paired device offers Connect, Trust and Forget; an unpaired one offers Pair. ## Battery has two sources The row shows a percentage when it can find one, from either of two places: - `BluetoothDevice.battery` / `batteryAvailable`, which is BlueZ's `org.bluez.Battery1`. Audio devices push this live. Nothing to poll. - A kernel `power_supply`, read by the module on a 30s timer while anything is connected. Gamepads are the reason: a Sony pad publishes no `Battery1`, it exposes the charge as `/sys/class/power_supply/ps-controller-battery-` (DualSense) or `sony_controller_battery_` (DS4). The module reads every supply whose name ends in a MAC and keys it by the address, so the driver and its separator do not matter. BlueZ wins when both exist. Neither source knowing the device leaves the field empty, never a zero. ## Pairing is the one shell-out Quickshell ships no BlueZ pairing agent and no generic D-Bus module, so a device that requires a passkey or PIN confirmation has no way to prompt from QML. `Pairing.qml` runs `bluetoothctl --timeout 20 pair
`, whose own agent handles the prompt. Everything else is native `Quickshell.Bluetooth`. The cost is that `bluetoothctl` is the ceiling: a device it cannot auto-confirm times out and the error shows, rather than pairing. `Pairing.qml` carries a `ponytail:` comment naming that and the upgrade path. ## Not built Connecting and forgetting report no failure signal in the BlueZ binding; only pairing does, through the `bluetoothctl` exit code. A connect that fails shows only as the device staying unconnected. ## Service lifetime `alwaysActive: true`, and truthfully: the BlueZ backend pushes, there is no poll to gate, and there is no `Service.qml`. Referencing `Bluetooth` in `BluetoothModule.qml` instantiates it at shell start. The adapter is null and the device list empty for about two seconds after launch. Every access navigates safely; nothing caches the first paint.