Architecture Overview
High-Level Design
ashell is structured in three layers:
┌──────────────────────────────────────────────────┐
│ main.rs │
│ (logging, CLI args, iced daemon) │
└──────────────────────┬───────────────────────────┘
│
┌──────────────────────▼───────────────────────────┐
│ Core Layer │
│ app.rs · config.rs · outputs.rs · theme.rs │
│ menu.rs · password_dialog.rs │
│ │
│ Central state, message routing, config, │
│ multi-monitor management, theming │
└───────┬──────────────────────────────┬───────────┘
│ │
┌───────▼──────────┐ ┌─────────────▼────────────┐
│ Modules (UI) │ │ Services (Backend) │
│ │ │ │
│ tempo, │ │ compositor, audio, │
│ workspaces, │ │ bluetooth, network, │
│ settings, │◄───│ mpris, tray, upower, │
│ system_info, │ │ brightness, privacy, │
│ notifications, │ │ notifications, logind, │
│ tray, media, │ │ idle_inhibitor │
│ privacy, etc. │ │ │
└──────────────────┘ └──────────────────────────┘
- Core Layer: The
Appstruct owns all state. It routes messages, manages windows/surfaces, and coordinates modules. - Modules: Self-contained UI components displayed in the bar. Each module has its own
Messagetype,view(),update(), andsubscription(). - Services: Backend integrations that produce events and accept commands. They have no UI. Modules consume services via subscriptions.
Why iced?
iced is a cross-platform GUI library for Rust that follows the Elm Architecture (Model-View-Update). It was chosen for ashell because:
- Rust-native: No FFI bindings to GTK/Qt, keeping the stack uniform.
- Elm Architecture: Predictable state management with unidirectional data flow.
- Wayland layer shell support: Available through iced_layershell.
- GPU-accelerated rendering: Via wgpu.
iced_layershell
ashell uses upstream iced 0.14 with iced_layershell, a Wayland layer shell backend built on Smithay Client Toolkit (SCTK). This provides layer surface management, multi-surface support, and input handling without forking iced.
In Cargo.toml the dependency is aliased as iced for convenience:
iced = { package = "iced_layershell", git = "https://github.com/MalpenZibo/iced_layershell", tag = "v0.1.3", features = [...] }
History: ashell previously depended on a Pop!_OS/cosmic-iced fork chain. The migration to iced_layershell (v0.8.0+) eliminated that fork dependency.
Design Principles
- Modular: Each module is self-contained and optional. Adding or removing a module should not affect others.
- Reactive: State flows in one direction. Events come in through subscriptions, state is updated, and the view re-renders.
- Service-agnostic UI: Modules don’t directly interact with system APIs. They consume data from services, making the UI layer testable and compositor-independent.
- Configuration-driven: Everything is configurable via a TOML file with sensible defaults. The bar works out of the box with zero configuration.