- C/GTK source under
src/is the source of truth; Meson builds two executables:build/src/bm-sidebarCLI andbuild/src/bm-sidebar-guihelper. - Root
bm-sidebaris only a checkout launcher forbuild/src/bm-sidebar; packaged installs put the CLI under/usr/binand the helper under/usr/libexec/bm-sidebar/. - CLI parsing lives in
src/cli/cli.c, process startup/helper exec lives insrc/cli/main.c, the GUI helper entrypoint issrc/app/main.c, and the Adw application is composed insrc/app/application.c. - UI construction is split between
src/sidebar/sidebar-window.candsrc/app/application-pages.c; BlueZ, OBEX, settings, paths, audio profile, and IPC integration live in dedicatedsrc/*/modules.
- Waybar invokes
/home/relz/.local/bin/bm-sidebar --toggle; that wrapper execs this repo's./bm-sidebar. - Keep the CLI GTK/libadwaita/BlueZ/OBEX/audio-free:
--helpand IPC attempts must not initialize GUI or live Bluetooth/audio services. - CLI commands are mutually exclusive:
--toggle,--show,--hide,--quit,--reload-css,--background; default is--toggle;--hide,--quit, and--reload-cssare IPC-only. - IPC uses a Unix socket named
bm-sidebar.sockunderXDG_RUNTIME_DIR, or/tmp/bm-sidebar-$UIDif unset. - IPC uses newline-framed commands with acknowledgement responses;
--backgroundverifies a responsive command server withping. - Preserve IPC runtime directory owner/type/permission/symlink checks, startup locking, stale-socket probing, and acknowledged responses.
- Settings save to
${XDG_CONFIG_HOME:-~/.config}/bm-sidebar/settings.json; load falls back to legacybluetooth-sidebar/settings.jsononly when the new file is absent; default received files directory is~/Downloads. - CSS is loaded from this repo's
bm-sidebar.cssduring checkout runs, from/usr/share/bm-sidebar/bm-sidebar.csswhen packaged, and user overrides from${XDG_CONFIG_HOME:-~/.config}/bm-sidebar/bm-sidebar.csscan be reloaded with--reload-css. - Output targeting comes from
BM_SIDEBAR_OUTPUT, then Waybar'sWAYBAR_OUTPUT_NAME, and is forwarded over IPC before showing the layer-shell panel. - Gtk4LayerShell is required to show the sidebar; keep protocol/version guards for optional APIs and keyboard mode compatibility.
- Audio profile actions shell out to
pactl; Bluetooth unblock recovery shells out torfkill unblock bluetooth.
- BlueZ state comes from ObjectManager on the system bus; OBEX file transfer uses
org.bluez.obexon the session bus. - The app registers a default BlueZ pairing agent at
/dev/relz/BmSidebar/Agentwith capabilityKeyboardDisplay. - Discovery auto-stops after
BLUEZ_SCAN_TIMEOUT_SECONDSinsrc/bluez/bluez-discovery.c. - Pair, trust, connect, disconnect, remove, block, power, discoverable, audio profile, and file-transfer actions mutate live system Bluetooth/audio state.
- Ask before adding new behavior that blocks/unblocks, powers off, disconnects, removes, changes trust/pairing, changes audio profiles, or changes file-transfer policy unless the user explicitly requested it.
- If
build/is missing, runmeson setup build; build withmeson compile -C build. - No test-suite, lint, formatter, or typecheck config is present; use focused checks after edits.
- Check CLI parsing without starting the UI using
./bm-sidebar --help. - Check the Waybar wrapper with
/home/relz/.local/bin/bm-sidebar --help. - In a Wayland graphical session, smoke-test the panel with
(./bm-sidebar --show & pid=$!; sleep 2; ./bm-sidebar --quit; wait $pid). - Package metadata lives under
packaging/;.github/workflows/build-packages.ymlbuilds packages only forv*.*.*tags and syncs Meson project version from the tag. - If adding packaged runtime files, update Meson install rules and
packaging/nfpm.yamltogether. - If runtime dependencies change, update
README.md,packaging/nfpm.yaml, andpackaging/aur/PKGBUILD.intogether.