Skip to content

feat(linux): add Linux x64 support over BlueZ - #256

Open
Sayzx wants to merge 3 commits into
SpriteOvO:mainfrom
Sayzx:linux-port
Open

Sayzx wants to merge 3 commits into
SpriteOvO:mainfrom
Sayzx:linux-port

Conversation

@Sayzx

@Sayzx Sayzx commented Oct 12, 2026 •

Copy link
Copy Markdown

Motivation

AirPodsDesktop is Windows-only. This PR adds Linux x64 support so the same AirPods status, lid popup and battery display work on BlueZ-based desktops.

Behaviour changes

  • Linux backend: Bluetooth discovery, connection state and advertisements go through BlueZ over D-Bus. Media control, autostart and quick connect have Linux implementations behind the existing platform interfaces.
  • Scanner lifetime (all platforms): the advertisement scanner keeps running while a device is bound, even when it is disconnected. Before, it stopped on disconnect, and advertisements were ignored until the device reconnected.
  • Connect on lid open (all platforms): opening the case with the bound device disconnected asks the OS to connect it. Device::Connect() is a no-op by default, so Windows still relies on the OS to connect.
  • Lid popup: the window follows the lid state alone. Pods taken out of the case with the lid open show the window and replay the animation.
  • Animation (all platforms): the video stays loaded while the window is hidden and restarts from the beginning on show, instead of reloading the file each time.

No settings, ABI or persisted data changed. kFieldsAbiVersion is untouched.

Packaging

  • Packaging/Linux/make-bundle.sh: a self-contained directory and tarball with the Qt libraries and plugins the application loads.
  • Packaging/Linux/make-deb.sh: a .deb that installs under /opt, exposes /usr/bin/AirPodsDesktop, and declares the system libraries it needs.
  • Docs/Build.md: Linux prerequisites, build steps and both packages.

Testing

  • Ubuntu 24.04, GCC 13.3, Qt 6.8.3, BlueZ 5.72, X11.
  • ctest: all 13 suites pass, including the new LinuxPlatformTests.
  • Manual: AirPods Pro connected and bound. Connect on lid open, popup on lid open, popup and animation replay when pods leave the case. The extracted .deb starts with the French locale. The .deb was installed with sudo apt install ./<file>.deb on the same Ubuntu 24.04 machine and the app runs from the menu.

Not tested

  • Windows is not built or tested by this PR. The shared paths above (scanner lifetime, connect on lid open, lid popup, animation playback) also run on Windows and need a check there.
  • Other AirPods models, Wayland sessions, and other distributions. The .deb dependency list comes from the Ubuntu 24.04 package names.

Notes for review

  • The commits are split into the Linux port, packaging and docs, and README credits. The port commit mixes the shared-behaviour changes listed above with the Linux backend, because they touch the same files.
  • The Linux port adds Qt6::DBus on Linux only. BlueZ must be running at runtime.

🤖 Generated with Claude Code

Sayzx added 3 commits October 12, 2026 14:40
Port the application to Linux x64. Bluetooth discovery, connection state and
advertisements go through BlueZ over D-Bus. Media control, autostart and quick
connect have Linux implementations behind the existing platform interfaces.

- Add the BlueZ D-Bus helper and the Linux Bluetooth, media, autostart and
  quick-connect backends.
- Keep scanning while a device is bound, even when it is disconnected, and
  request a connection when the case lid opens (asynchronous Device1.Connect).
- Show the window when the lid opens or when the pods leave the case with the
  lid open. The window follows the lid state alone.
- Keep the animation video loaded while the window is hidden and replay it from
  the start on show, instead of reloading the file each time.
- Add Linux platform tests and the desktop entry used by cmake --install.

Tested on Ubuntu 24.04 with Qt 6.8.3, BlueZ and AirPods Pro. Shared code paths
(scanner lifetime, lid popup) also run on Windows; that is not built or tested.
Packaging/Linux/make-bundle.sh builds a self-contained directory and tarball:
the application, the Qt libraries and plugins it loads, a launcher and an
install.sh that adds a menu entry for the current user.

Packaging/Linux/make-deb.sh wraps a bundle into a .deb that installs under
/opt/AirPodsDesktop, exposes /usr/bin/AirPodsDesktop and declares the system
libraries the bundle loads as dependencies.

Docs/Build.md describes the Linux prerequisites, the build and both packages.
Keep README.md, README-CN.md and README-TW.md aligned in credits, as
AGENTS.md requires.
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