From a1d62dd085ac70fc90a05095220156897bdd8f82 Mon Sep 17 00:00:00 2001 From: Tommaso Negri Date: Tue, 11 Aug 2026 17:50:39 +0200 Subject: refactor daemons + mpd + documentation --- Sources/bar/bar.docc/bar.md | 1 + Sources/bar/bar.docc/daemons.md | 82 ++++++++++++++++++++++++++ Sources/bar/bar.docc/daemons/daemon-mpd.md | 34 +++++++++++ Sources/bar/bar.docc/daemons/daemon-volumed.md | 31 ++++++++++ 4 files changed, 148 insertions(+) create mode 100644 Sources/bar/bar.docc/daemons.md create mode 100644 Sources/bar/bar.docc/daemons/daemon-mpd.md create mode 100644 Sources/bar/bar.docc/daemons/daemon-volumed.md (limited to 'Sources') diff --git a/Sources/bar/bar.docc/bar.md b/Sources/bar/bar.docc/bar.md index eb4ff73..e49e402 100644 --- a/Sources/bar/bar.docc/bar.md +++ b/Sources/bar/bar.docc/bar.md @@ -29,6 +29,7 @@ If you specify the interval, the block will re-run the command with such frequen - - +- - ``Config`` - ``HEX`` diff --git a/Sources/bar/bar.docc/daemons.md b/Sources/bar/bar.docc/daemons.md new file mode 100644 index 0000000..e99ecfc --- /dev/null +++ b/Sources/bar/bar.docc/daemons.md @@ -0,0 +1,82 @@ +# Daemons + +Extend the program with companion processes. + +A *daemon* is a separate program that runs alongside *bar* and communicates with it via Darwin notifications (see ``Notifier``). +Unlike , daemons do not modify *bar*'s source code, they are independent binaries that you compile and run on their own. + +This approach keeps *bar* minimal and focused while still allowing it to react to system events like volume changes, network events, or battery status. +Daemons are written in C by default (though any language works), and each one is a single `.c` file that compiles with `cc`. + +> Tip: Daemons are a good fit for events that require system-level APIs (CoreAudio, IOKit, CGEvent, etc.) without pulling that complexity into *bar* itself. + +## How it works + +A daemon listens for some system signal and, when it fires, posts a Darwin notification: + +```c +notify_post("bar.touch."); +``` + +The ``Notifier`` system in *bar* receives the notification and re-runs the corresponding block's command. +The block itself stays stateless, it just reads and prints the current state whenever it is called. + +For example, the daemon listens for CoreAudio volume change events and posts `bar.touch.volume`. +The volume block in ``Config`` runs once per notification, prints the current volume, and the bar updates. + +## How to install + +Each daemon in the collection can be installed following the same pattern: + +1. Edit the daemon file to send the correct notification/s: +```c +// Search in the file for a line like +notify_post("bar.touch."); + +// Replace it with the correct block name +notify_post("bar.touch.volume"); + +// If you want to update multiple blocks, just add +// another line below the first one +notify_post("bar.touch.volume"); +notify_post("bar.touch.music"); +``` + + +2. Compile the daemon: +```shell +cc -o ~/.local/bin/ daemons/.c -framework +``` + +3. (Optional) Create a launch agent for automatic startup. +The process is very similar to the one described in the article. + +## Topics + +### Audio + +- + + + + + + + + + + + + + + + +### Media + +- + + + + + + diff --git a/Sources/bar/bar.docc/daemons/daemon-mpd.md b/Sources/bar/bar.docc/daemons/daemon-mpd.md new file mode 100644 index 0000000..000d7a1 --- /dev/null +++ b/Sources/bar/bar.docc/daemons/daemon-mpd.md @@ -0,0 +1,34 @@ +# mpd + +React to MPD (Music Player Daemon) track changes. + +This daemon connects to MPD via TCP and uses the `idle` command to block until the player state or playlist changes. When it does, it posts a Darwin notification that tells *bar* to refresh the desired block. + +## How it works + +MPD's protocol has an `idle` command designed exactly for this purpose. You send `idle player playlist options` and the connection blocks until something changes. No polling, no busy-waiting. + +When the `idle` command returns, the daemon calls `notify_post("bar.touch.")` and immediately re-enters idle mode. + +The ``Notifier`` system in *bar* picks this up and re-runs the block's command. + +### Dependencies + +None — uses only standard POSIX sockets and `notify.h`, both available on every Mac. + +### Configuration + +The daemon respects the same environment variables as `mpc`: + +- `MPD_HOST` — MPD server hostname (default: `localhost`) +- `MPD_PORT` — MPD server port (default: `6600`) + +## Compile + +```shell +cc -o bar-mpd daemons/mpd.c +``` + +## Author + +Tommaso Negri [@tommasongr](https://github.com/tommasongr) diff --git a/Sources/bar/bar.docc/daemons/daemon-volumed.md b/Sources/bar/bar.docc/daemons/daemon-volumed.md new file mode 100644 index 0000000..1b06102 --- /dev/null +++ b/Sources/bar/bar.docc/daemons/daemon-volumed.md @@ -0,0 +1,31 @@ +# volumed + +React to volume and mute changes. + +This daemon listens for system volume changes via **CoreAudio** and posts a Darwin notification that tells *bar* to refresh the desired block. +Because it uses CoreAudio's property listeners instead of an event tap, **no Accessibility permission is required**. + +## How it works + +The daemon registers a CoreAudio property listener on the default output device for: +- `kAudioDevicePropertyVolumeScalar` — fires when the volume level changes. +- `kAudioDevicePropertyMute` — fires when the mute state toggles. + +When either property changes, the daemon calls `notify_post("bar.touch.")`. +The ``Notifier`` system in *bar* picks this up and re-runs the block's command. + +The daemon also watches for output device changes (e.g. plugging in headphones) and re-registers the listener on the new device. + +### Dependencies + +- CoreAudio.framework — system framework, shipped with macOS. + +## Compile + +```shell +cc -o bar-volumed daemons/volumed.c -framework CoreAudio +``` + +## Author + +Tommaso Negri [@tommasongr](https://github.com/tommasongr) -- cgit v1.2.3