Inobtrusive set of Linux/Wayland/GTK apps intended to control primary system functions from single place.
Pop up overview panel, that gives summary status of about everything to quickly see the situation report and do minor settings.
- Audio volume
- Bluetooth devices
- Brightness
- Dark mode
- Keyboard layout
- Notifications
- Night Light
- VPN
- Time
- Tiny calendar
- Todays agenda
- Wifi
- Wired network
- ...and more
This app also renders transient notification toasts.
Detailed control center for the entire system.
Tiny extensible pop up launcher.
Everything is built around the central daemon (waft) that discovers, spawns, and supervises plugins. It routes entity updates and actions between plugins and apps via Unix sockets. The plugins provide data and methods to the UI apps and the apps provide interface to the user.
cargo build --workspace
cargo test --workspaceAUR package tracks:
waft-git— VCS/source-built packagewaft-bin— stable package repackaging prebuilt GitHub Release artifacts
Release automation and AUR publication flow are documented in:
docs/release-process.md
# Start the central daemon (or let D-Bus activation start it)
waft
# Start the overlay
waft-overview
# Development: run daemon with plugins from build output
WAFT_DAEMON_DIR=./target/debug waftConfiguration is loaded from ~/.config/waft/config.toml.
[[plugins]]
id = "plugin::clock"
[[plugins]]
id = "plugin::darkman"
[[plugins]]
id = "plugin::notifications"
toast_limit = 3
disable_toasts = false
[[plugins]]
id = "power"Legacy [[plugins]] id = "battery" remains accepted as a config alias for one release cycle.
All plugins are standalone daemon binaries implementing the Plugin trait from waft-plugin. They provide domain entities to the central daemon, which routes updates to subscribed apps.
| Plugin | Binary | Entity Types | Description |
|---|---|---|---|
| clock | waft-clock-daemon | clock |
Date and time with locale support |
| darkman | waft-darkman-daemon | dark-mode |
Dark mode toggle via darkman D-Bus |
| caffeine | waft-caffeine-daemon | sleep-inhibitor |
Prevent sleep/screensaver via Portal |
| power | waft-power-daemon | battery, power-profile |
Battery status via UPower and power profile management via power-profiles-daemon |
| brightness | waft-brightness-daemon | display |
Display brightness via brightnessctl/ddcutil |
| keyboard-layout | waft-keyboard-layout-daemon | keyboard-layout |
Input method display/switch (Niri/Sway/Hyprland/localed) |
| systemd-actions | waft-systemd-actions-daemon | session |
Lock, logout, reboot, shutdown, suspend |
| bluez | waft-bluez-daemon | bluetooth-adapter, bluetooth-device |
Bluetooth management via BlueZ D-Bus |
| audio | waft-audio-daemon | audio-device |
Volume sliders and device selection via pactl |
| networkmanager | waft-networkmanager-daemon | network-adapter, wifi-network, ethernet-connection, vpn |
WiFi/Ethernet/VPN via NetworkManager |
| weather | waft-weather-daemon | weather |
Weather info via Open-Meteo API |
| notifications | waft-notifications-daemon | notification, dnd |
D-Bus notification server; overview renders toasts and history |
| eds | waft-eds-daemon | calendar-event |
Calendar integration via Evolution Data Server |
| sunsetr | waft-sunsetr-daemon | night-light |
Night light control via sunsetr CLI |
| syncthing | waft-syncthing-daemon | backup-method |
Syncthing service toggle |
See ARCHITECTURE.md for the full entity-based architecture design.
| Crate | Path | Purpose |
|---|---|---|
waft-protocol |
crates/protocol/ |
Entity types, messages, URN format, transport |
waft-plugin |
crates/plugin/ |
Plugin SDK: Plugin trait, PluginRuntime, EntityNotifier |
waft |
crates/waft/ |
Central daemon: routing, lifecycle, discovery |
waft-overview |
crates/overview/ |
GTK4 overlay app with WaftClient |
waft-ui-gtk |
crates/waft-ui-gtk/ |
GTK4 widget library: WidgetReconciler, widget implementations |
waft-config |
crates/config/ |
TOML configuration loading |
waft-i18n |
crates/i18n/ |
Fluent localization |
waft-core |
crates/core/ |
Common types: Callback, DbusHandle |
waft-ipc |
crates/ipc/ |
Legacy widget protocol (being phased out) |
Plugin (daemon) <--> waft (central daemon) <--> waft-overview (GTK app)
- Plugins provide entities (typed domain data) to the daemon
- Apps subscribe to entity types and receive push updates
- Actions flow from apps through the daemon to the owning plugin
- Transport: length-prefixed JSON over Unix sockets
- GTK widgets live on the main thread (not
Send/Sync) - Plugin daemons are pure tokio (all
Send + Sync) - GTK-to-daemon writes:
std::sync::mpsc+ OS thread (bypasses tokio) - Daemon-to-GTK reads: tokio task -> flume ->
glib::spawn_future_local
The notifications plugin owns org.freedesktop.Notifications on D-Bus and supports:
- Notifications with actions, body, and body-markup
- In-memory storage (not persisted across restarts)
- Action invocation and notification replacement
- Do Not Disturb mode
- darkman for dark mode toggling
- sunsetr for night light control
- brightnessctl / ddcutil for display brightness
- pactl (PipeWire/PulseAudio) for audio control
See LICENSE file.