Skip to content

fix(battery): prefer Mains/USB supplies when auto-detecting the adapter - #5269

Open
klizas wants to merge 1 commit into
Alexays:masterfrom
klizas:fix/battery-adapter-detection
Open

fix(battery): prefer Mains/USB supplies when auto-detecting the adapter#5269
klizas wants to merge 1 commit into
Alexays:masterfrom
klizas:fix/battery-adapter-detection

Conversation

@klizas

@klizas klizas commented Aug 23, 2026

Copy link
Copy Markdown

What does this PR do?

Fixes battery adapter auto-detection picking the battery itself as the adapter.

When no "adapter" is configured, refreshBatteries() assigns adapter_ to the last node in /sys/class/power_supply that has online or status. Batteries match through status, so whether the real adapter or the battery wins depends on readdir order. A battery has no online, so when the battery wins, every adapter_ check reads offline: the Not charging -> Plugged upgrade and full-at-plugged are silently dead.

Observed on a MacBookPro16,1 (kernel 7.2.0-1-cachyos-t2): ADP1 (ACPI0003:00, type Mains, has online, no status) iterates before BAT0 (ACPI0002:00, type Battery, has status, no online), so BAT0 always won and the bar showed the discharging/not-charging format while plugged in. Pinning "adapter": "ADP1" was the only workaround.

The fix classifies candidates by type and picks in priority order:

  1. node matching a configured "adapter" name (unchanged behavior)
  2. Mains
  3. USB* (prefix match, so legacy pre-4.19 types like USB_PD count)
  4. any other online-capable supply (Wireless, UPS, missing type file)
  5. status-only nodes, as a last resort

First match wins within each tier. If a pass finds nothing, adapter_ keeps its previous value, as before.

Tested live on the machine above: before, Waybar picked BAT0, patched now picks ADP1, and Plugged works without a pin. Also compared old and new selection over nine mocked sysfs layouts (battery-only, Mains+battery, Mains+USB-C source nodes, legacy USB_PD, wireless charger, UPS-only, typeless online node, empty dir, two batteries): the new logic finds an adapter in every case the old one did, and picks the same node everywhere except the order-dependent broken cases. Battery-only machines still get the battery as adapter_, and the configured-name path is identical.

Related issues

None found

Checklist

  • Code is formatted with clang-format
  • Builds locally (ninja -C build)
  • Man page updated for any new/changed user-facing option (man/) — N/A, no new option; adapter docs already say "instead of auto detect"
  • Tested against the affected module(s)

Without an "adapter" pin, adapter_ got the last node in
/sys/class/power_supply with `online` or `status`. Batteries match via
`status`, so the battery itself could win, and a battery has no
`online`, so the "Plugged" state never showed. Pick by class instead:
Mains > USB* > other online-capable > status-only. A configured
"adapter" name still wins unchanged.
@klizas
klizas marked this pull request as ready for review August 23, 2026 19:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant