ReadyPlayerNaN/waft

★ 0Forks 0RustGitHub ↗Compare

README

waft

Inobtrusive set of Linux/Wayland/GTK apps intended to control primary system functions from single place.

Components

waft-overview

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.

waft-settings

Detailed control center for the entire system.

waft-launcher

Tiny extensible pop up launcher.

Architecture

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.

Building

cargo build --workspace
cargo test --workspace

Packaging and releases

AUR package tracks:

  • waft-git — VCS/source-built package
  • waft-bin — stable package repackaging prebuilt GitHub Release artifacts

Release automation and AUR publication flow are documented in:

  • docs/release-process.md

Running

# 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 waft

Configuration

Configuration 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.

Plugins

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

Architecture

See ARCHITECTURE.md for the full entity-based architecture design.

Crate Structure

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)

Communication Flow

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

Threading Model

  • 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

Notification Server

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

External Dependencies

License

See LICENSE file.

Contributors

ReadyPlayerNaNsijsss

Issues