aboutsummaryrefslogtreecommitdiff
path: root/Sources
diff options
context:
space:
mode:
authorTommaso Negri <me@tommasongr.com>2026-08-11 17:50:39 +0200
committerTommaso Negri <me@tommasongr.com>2026-08-11 17:50:39 +0200
commita1d62dd085ac70fc90a05095220156897bdd8f82 (patch)
tree2af6218e0c9e2a6e399cf5f91e3a0ba05e7c3014 /Sources
parent4dcbad96f8dc63c5f48d063606f0384853ac799d (diff)
downloadbar-a1d62dd085ac70fc90a05095220156897bdd8f82.tar.gz
bar-a1d62dd085ac70fc90a05095220156897bdd8f82.zip
refactor daemons + mpd + documentation
Diffstat (limited to 'Sources')
-rw-r--r--Sources/bar/bar.docc/bar.md1
-rw-r--r--Sources/bar/bar.docc/daemons.md82
-rw-r--r--Sources/bar/bar.docc/daemons/daemon-mpd.md34
-rw-r--r--Sources/bar/bar.docc/daemons/daemon-volumed.md31
4 files changed, 148 insertions, 0 deletions
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
- <doc:customisation>
- <doc:patches>
+- <doc:daemons>
- ``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 <doc:patches>, 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.<block-name>");
+```
+
+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 <doc:daemon-bar-volumed> 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.<block-name>");
+
+// 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/<daemon-name> daemons/<daemon-name>.c -framework <dependency>
+```
+
+3. (Optional) Create a launch agent for automatic startup.
+The process is very similar to the one described in the <doc:run-at-login> article.
+
+## Topics
+
+### Audio
+
+- <doc:daemon-volumed>
+<!-- - <doc:daemon-bar-micd> -->
+
+<!-- ### Display -->
+<!---->
+<!-- - <doc:daemon-bar-brightnessd> -->
+<!-- - <doc:daemon-bar-spaced> -->
+<!---->
+<!-- ### Power -->
+<!---->
+<!-- - <doc:daemon-bar-batteryd> -->
+<!---->
+<!-- ### Network -->
+<!---->
+<!-- - <doc:daemon-bar-networkd> -->
+
+### Media
+
+- <doc:daemon-mpd>
+<!-- - <doc:daemon-bar-nowplayingd> -->
+
+<!-- ### System -->
+<!---->
+<!-- - <doc:daemon-bar-focusd> -->
+<!-- - <doc:daemon-bar-devicesd> -->
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.<block-name>")` 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.<block-name>")`.
+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)