Skip to content

bluetooth: try getting battery percentage from upower if missing from bluez#2967

Open
jinliu wants to merge 1 commit into
noctalia-dev:mainfrom
jinliu:feature/bluetooth-batt-upower
Open

bluetooth: try getting battery percentage from upower if missing from bluez#2967
jinliu wants to merge 1 commit into
noctalia-dev:mainfrom
jinliu:feature/bluetooth-batt-upower

Conversation

@jinliu

@jinliu jinliu commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Bluetooth widget / tab will now also query UPowerService for battery percentage if BluetoothService doesn't provide it.

An example of this is the Playstation 5 controller.

Copilot AI review requested due to automatic review settings June 10, 2026 09:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a UPower-based fallback to display Bluetooth device battery percentages when BlueZ doesn’t report them.

Changes:

  • Pass UPowerService* into Control Center’s BluetoothTab and the bar BluetoothWidget.
  • Query UPower by Bluetooth address to show battery % in the device list rows and widget tooltip.
  • Normalize Bluetooth addresses via StringUtils::toLower(...) before querying UPower.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/shell/control_center/control_center_panel.cpp Wires UPowerService* into BluetoothTab construction.
src/shell/control_center/bluetooth_tab.h Extends BluetoothTab API to accept/store UPowerService*.
src/shell/control_center/bluetooth_tab.cpp Uses UPower as fallback battery source for device rows.
src/shell/bar/widgets/bluetooth_widget.h Extends BluetoothWidget API to accept/store UPowerService*.
src/shell/bar/widgets/bluetooth_widget.cpp Uses UPower as fallback battery source in tooltip.
src/shell/bar/widget_factory.cpp Passes m_upower into BluetoothWidget creation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/shell/control_center/bluetooth_tab.cpp Outdated
Comment thread src/shell/bar/widgets/bluetooth_widget.cpp
Comment thread src/shell/bar/widgets/bluetooth_widget.cpp
… bluez

Bluetooth widget / tab will now also query UPowerService for battery percentage
if BluetoothService doesn't provide it.

An example of this is the Playstation 5 controller.
@jinliu jinliu force-pushed the feature/bluetooth-batt-upower branch from 1917b26 to 29d15fb Compare June 12, 2026 03:04
@ItsLemmy

Copy link
Copy Markdown
Collaborator

Thanks for this! a few things before merge:

Blocker: the toLower will break the lookup. deviceForSelector → selectorMatchesField does a case-sensitive match and doesn't normalize the stored UPower fields. BlueZ reports Address in uppercase and UPower mirrors that uppercase MAC into the device serial, so a lowercased selector (aa:bb:...) won't match the uppercase serial (AA:BB:...), the lookup returns null and the feature is inert. Please pass d.address verbatim instead of StringUtils::toLower(d.address) at both call sites (and you can drop the two new util/string_utils.h includes). Verbatim matches serial exactly, and it keeps the shared selector matcher case-sensitive, making it case-insensitive would change behavior for the user-facing battery device selector too.

Staleness of the fallback value. The UPower-derived percentage isn't part of any invalidation key, and luetoothService emits no signal when UPower's percentage changes, so the value can drift after it's first shown:

  • BluetoothTab::listKey() includes bluez batteryPercent but not the UPower fallback, so it rebuilds on bluez battery changes but not UPower ones.
  • BluetoothWidget::syncState()'s early-return key doesn't include battery at all.

It'll render ok on connect (that triggers a rebuild), but won't update afterward. A complete fix needs both: subscribe to UPowerService's change callback to pump requestUpdate()/rebuild, and fold the resolved percentage into the keys so the rebuild isn't suppressed. It's fine to scope that to a follow-up if you'd rather.

Minor:

  • control_center_panel.cpp still has a stale (void)upower; now that upower is actually used.
  • The new upower_service.h includes in the two headers can be forward declarations (class UPowerService;) — only used as pointers there.
  • static_cast(percentage) truncates rather than rounds (minor, and inconsistent with the uint8_t cast in the widget).

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.

3 participants