summaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
authorAsko Nõmm <asko@nmm.ee>2026-04-29 20:45:04 +0300
committerAsko Nõmm <asko@nmm.ee>2026-04-29 20:45:04 +0300
commita6b024ffbc0052813d5cfd05fa2cd207d5b20c9b (patch)
treef0c9c606888e0d3de77c3a39c2df129eae5c0072 /README.md
Initial commit: Rust notification badge daemon for KDE Plasma 6
Monitors D-Bus for desktop notifications and emits Unity LauncherEntry badge updates so KDE Plasma task manager shows notification counts. - Streaming dbus-monitor parser with app matching and lifecycle tracking - KWin window discovery for automatic desktop file detection - Systemd user service, Makefile install/uninstall targets - 38 tests (32 unit + 6 integration), 97% line coverage via cargo-llvm-cov - CodeScene code health: 10/10 on all source files
Diffstat (limited to 'README.md')
-rw-r--r--README.md98
1 files changed, 98 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..fc05259
--- /dev/null
+++ b/README.md
@@ -0,0 +1,98 @@
+# notification-badge
+
+Taskbar badge notifications for KDE Plasma 6. Dynamically discovers running applications via KWin, monitors desktop notifications via D-Bus, and sets badge counts on taskbar icons using the Unity Launcher API. No hardcoded app list needed.
+
+## How it works
+
+1. **Discovers apps dynamically** by querying KWin via D-Bus — enumerates open windows using `WindowsRunner.Match`, then calls `KWin.getWindowInfo` for each to get the `desktopFile` property. Rediscovers every 30 seconds in a background thread.
+2. Runs an **unfiltered `dbus-monitor --session`** subprocess (unfiltered is required to capture method return messages which contain the assigned notification ID).
+3. Parses the dbus-monitor output as a stream, tracking three message types:
+ - `method_call` with `member=Notify` — extract the `app_name` and message `serial`
+ - `method_return` with matching `reply_serial` — extract the notification ID
+ - `signal` with `member=NotificationClosed` — notification was dismissed
+4. Matches `app_name` (case-insensitive) against the dynamically discovered app map. Also supports Flatpak apps via `desktop-entry` hints.
+5. Emits `com.canonical.Unity.LauncherEntry.Update` signals via `gdbus emit` to set/clear badge counts and the `urgent` flag on the corresponding taskbar icon.
+6. On shutdown (SIGINT/SIGTERM), clears all badges.
+
+## Requirements
+
+- KDE Plasma 6 with KWin and Task Manager
+- `dbus-monitor` (from `dbus-tools`, typically pre-installed)
+- `gdbus` (from `glib2`, typically pre-installed)
+- Rust toolchain (to build)
+
+## Install
+
+```bash
+git clone https://github.com/example/notification-badge.git
+cd notification-badge
+make install
+```
+
+This installs the binary to `~/.local/bin/` and the systemd service to `~/.config/systemd/user/`.
+
+### Enable at login
+
+```bash
+systemctl --user enable --now notification-badge.service
+```
+
+### Check status
+
+```bash
+systemctl --user status notification-badge.service
+journalctl --user -u notification-badge.service -f
+```
+
+## Uninstall
+
+```bash
+make uninstall
+```
+
+## Usage
+
+Run manually (logs to stderr):
+
+```bash
+notification-badge
+```
+
+Test with a sample notification:
+
+```bash
+notify-send --app-name=firefox "Test" "Badge should appear"
+```
+
+## Development
+
+```bash
+cargo test # run all tests
+cargo build # debug build
+make build # release build
+```
+
+## Architecture
+
+The crate is split into four modules:
+
+| Module | Purpose |
+|---|---|
+| `parser` | Streaming parser for `dbus-monitor` text output |
+| `app_map` | Tracks discovered apps, pending notifications, and active badge counts |
+| `discovery` | Queries KWin D-Bus interfaces to discover running apps and their desktop file IDs |
+| `badge` | Emits Unity LauncherEntry Update signals via `gdbus` |
+
+All modules are designed for testability — external D-Bus calls are injected as function parameters in tests.
+
+## Known limitations
+
+- Processes all session bus traffic (unfiltered monitor). Lightweight in practice but could theoretically be optimized with `BecomeMonitor` D-Bus API.
+- Only badges apps that currently have an open window. Pinned taskbar icons without a running instance won't be badged.
+- If two apps share the same last dot-segment in their desktop file ID, they would collide in the match map. Unlikely in practice.
+- Firefox web app notifications all badge under the single Firefox icon.
+- Notifications that expire via timeout also emit `NotificationClosed`, so badges clear when notifications auto-dismiss.
+
+## License
+
+MIT