โ† Back to projects

harald

A native Windows tray application for quick management of Bluetooth audio devices, written in C-style C++ against the raw Win32 API. One click to connect or disconnect your checked devices. Has build-in mini-installer.

Windows 10/11 Win32 / C++20 โ‰ˆ171 KB zlib licence v1.0

v1.0.24 ยท 91.4 KB ยท sha256: f423db2dcbac5766be3ca1f1865f5bb8465a899c497a188f05f20e69d1b7ae3d

Overview

harald lives quietly in the system tray and gives Bluetooth audio devices a single, fast entry point. Check the devices you care about in the menu, then left-click the tray icon to connect or disconnect them all at once. The whole thing starts in under 100 ms and uses a hand-rolled arena allocator instead of the heap.

Highlights

๐Ÿ–ฑ๏ธ

One-click toggle

Check devices in the menu, single-click to connect/disconnect them together.

๐ŸŒ—

Theme aware

Follows the Windows dark/light theme; the menu redraws on system colour changes.

โšก

Three connect paths

API (BluetoothSetServiceState), HCI link drop, or UI Automation โ€” pick per action.

๐Ÿ””

Toast notifications

Native Windows toasts name the devices; failure alerts on, success optional.

๐ŸŽต

Media automation

Optionally pause on disconnect and play on connect.

๐Ÿ“‚

Open data folder

Middle-click the tray icon to jump to %LOCALAPPDATA%\harald.

How it works

harald runs two threads. The UI thread owns the tray icon and three custom-drawn popup windows (menu, settings, inline message) and never blocks. The worker thread runs one connection batch at a time: discover paired audio devices, decide connect/disconnect, dispatch via the chosen method, then settle by re-discovering until the expected state holds. Results cross the boundary as fixed-size ToggleRequest structs signalled by a semaphore.

Build

Unity builds are on by default and a Release build auto-compresses with UPX when available:

  • MSVC: cmake --preset msvc && cmake --build --preset msvc
  • clang: cmake --preset clang && cmake --build --preset clang

Status

Actively maintained. Single instance enforced via named mutex; no telemetry, no data leaves the machine.