Skip to content

linux: clean up tray state when airpods disconnect during hibernation#553

Open
xxmathias wants to merge 1 commit intokavishdevar:mainfrom
xxmathias:fix/linux-hibernation-recovery
Open

linux: clean up tray state when airpods disconnect during hibernation#553
xxmathias wants to merge 1 commit intokavishdevar:mainfrom
xxmathias:fix/linux-hibernation-recovery

Conversation

@xxmathias
Copy link
Copy Markdown
Contributor

@xxmathias xxmathias commented Apr 28, 2026

The new Rust port is where this project is heading long-term, and I think that's a great direction. That said, I'm still using the Qt/C++ build day-to-day - it's the version I've come to rely on and personally prefer, so I'd love to keep it polished while the rewrite matures. Hope a small fix here is still welcome!

After waking from hibernation, the Linux app would leave the tray icon
stuck on the last battery percentage even when the AirPods were no longer
connected. The L2CAP socket state used by onSystemWakingUp is stale
across hibernation, and BlueZ may have torn down the connection without
the app seeing the PropertiesChanged signal.

What this PR does:

  • Replaces the socket-level areAirpodsConnected() check with a deferred
    BlueZ query (monitor->checkAlreadyConnectedDevices()), which is
    authoritative.
  • Wraps the check in a 1500 ms QTimer::singleShot so BlueZ's
    Connected property has time to settle after PrepareForSleep(false)
    and any pending bluezDeviceDisconnected signal can run the normal
    cleanup path first.
  • Routes a stale-but-disconnected device through onDeviceDisconnected,
    which resets DeviceInfo and the tray icon.

Test plan

  • Hibernate with AirPods connected, remove them from the case so they
    disconnect during sleep, then resume — tray icon resets to default,
    no stale battery %.
  • Hibernate with AirPods connected, leave them connected, then
    resume — A2DP profile is re-activated, tray keeps showing battery
    status, no false disconnect.
  • Tested on KDE Plasma 6 / Wayland.

After waking from hibernation, the L2CAP socket state can be stale and
BlueZ may have already torn down the connection without us seeing the
disconnect signal — leaving the tray stuck on the last battery percentage
even though the device is gone.

Replace the socket-state check with a deferred BlueZ query (the SNI
'Connected' property may not have settled yet at PrepareForSleep(false)
time), and route a stale-but-disconnected device through the normal
onDeviceDisconnected path so the tray icon and DeviceInfo are reset.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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