IPC Protocol & Common Types
Relevant source files
The following files were used as context for generating this wiki page:
The Kaleidux Inter-Process Communication (IPC) protocol facilitates communication between the core background service (kaleidux-daemon) and its command-line controller (kldctl). This system allows users to manage wallpaper transitions, playlists, and daemon states dynamically without restarting the service.
The protocol relies on Unix Domain Sockets for local transport and uses JSON-serialized messages for data exchange. This architecture ensures high-performance, low-latency control of the rendering pipeline. Common types defined across the project ensure that both the daemon and the controller share a unified understanding of requests, responses, and configuration states.
Sources: CONTRIBUTING.md:104-106, kaleidux-daemon/src/main.rs:541-550
IPC Architecture
The IPC system follows a Client-Server model. The kaleidux-daemon acts as the server, binding to a Unix socket and listening for incoming connections. The kldctl utility acts as the client, connecting to the socket to transmit Request objects and receive Response objects.
Socket Management
The daemon attempts to locate a suitable runtime directory for the socket. It prioritizes the XDG_RUNTIME_DIR, falling back to a user-specific path in /tmp if the former is unavailable. For security, the daemon sets the socket permissions to 0o600 (read/write for owner only) on Unix systems to prevent unauthorized access.
Sources: kaleidux-daemon/src/main.rs:541-561, kldctl/src/main.rs:172-181
Communication Flow
The communication is synchronous at the application level: the client sends a single JSON-encoded request, and the daemon returns a JSON-encoded response before closing the connection.
The diagram shows the lifecycle of an IPC transaction from command invocation to response display.
Sources: kaleidux-daemon/src/main.rs:564-586, kldctl/src/main.rs:183-200
Protocol Definition: Requests and Responses
The protocol is defined by two primary enums: Request and Response. These types are shared via the kaleidux-common library to ensure binary compatibility between the daemon and the controller.
Request Commands
Requests represent actions the daemon should perform.
| Request Variant | Description | Parameters |
|---|---|---|
QueryOutputs | Lists all connected monitors and their state. | None |
Next | Skips to the next wallpaper in the queue. | output: Option |
Prev | Returns to the previous wallpaper. | output: Option |
Love | Increases selection frequency for a file. | path: String, multiplier: f32 |
Pause / Resume | Controls video playback and cycling. | None |
Reload | Triggers a configuration reload from disk. | None |
Playlist | Managed playlist operations (Create, Add, Load). | cmd: PlaylistCommand |
Clear | Removes wallpaper to show a black screen. | output: Option |
Sources: kldctl/src/main.rs:136-169, kaleidux-daemon/src/main.rs:1047-1188
Response Types
The daemon responds to every request with a status or data structure.
| Response Variant | Description | Data Contained |
|---|---|---|
Ok | General success indicator. | None |
Error | Indicates a failure in processing. | String (Error message) |
OutputInfo | Returns monitor details. | Vec<OutputInfo> |
LoveitList | Returns the list of weighted files. | Vec<LoveitEntry> |
History | Returns recently played wallpapers. | Vec<PathBuf> |
Sources: kaleidux-daemon/src/main.rs:1048-1188, kldctl/src/main.rs:204-245
Transaction Sequence
The following sequence diagram illustrates the Next command flow across the IPC boundary:
Sequence of events for a specific monitor skip command via IPC.
Sources: kaleidux-daemon/src/main.rs:1066-1087, kldctl/src/main.rs:183-200
Common Data Structures
Several core structures are utilized by the IPC protocol to manage the state of the system, including output configurations and selection weights.
OutputInfo
Used in QueryOutputs to report monitor status to the user.
- name: The identifier (e.g., "eDP-1").
- width/height: Current resolution.
- current_wallpaper: Path to the active file.
Sources: kaleidux-daemon/src/main.rs:1050-1064
Loveit and File Stats
Selection frequency is managed via FileStats, which tracks usage and multipliers.
pub struct FileStats {
pub count: u32,
pub last_seen: Option<DateTime<Utc>>,
pub love_multiplier: f32, // 1.0 = normal, 2.0 = double chance
}
Sources: kaleidux-daemon/src/queue.rs:30-34
Selection Strategy
The SortingStrategy enum defines how the daemon picks the next file from the SmartQueue. This strategy can be overridden per output via the configuration file or IPC commands.
| Strategy | Description |
|---|---|
Loveit | Weighted random based on popularity and recency. |
Random | Pure random selection. |
Ascending | Alphabetical order. |
Descending | Reverse alphabetical order. |
Sources: kaleidux-daemon/src/orchestration.rs:20-27, kaleidux-daemon/src/queue.rs:364-411
Implementation Details
Server Command Handling
Inside kaleidux-daemon/src/main.rs, the handle_command function acts as the central dispatcher for all IPC requests. It is invoked within the main event loop to ensure that state changes (like switching wallpapers) occur on the correct thread.
async fn handle_command(
req: Request,
monitor_manager: &mut monitor_manager::MonitorManager,
// ... other parameters
) -> Response {
match req {
Request::QueryOutputs => {
// Logic to collect and return OutputInfo
}
Request::Next { output } => {
let changes = monitor_manager.handle_next(output);
// Logic to trigger renderer updates
Response::Ok
}
// ... other variants
}
}
Sources: kaleidux-daemon/src/main.rs:1047-1188
Persistent Storage Integration
The IPC commands for Love, Unlove, and Playlist management directly interact with the FileCache, which utilizes a redb database. This ensures that changes made via kldctl persist across daemon restarts.
Sources: kaleidux-daemon/src/cache.rs:18-25, kaleidux-daemon/src/queue.rs:434-442
Summary
The IPC Protocol and Common Types form the backbone of Kaleidux's extensibility and user control. By standardizing communication through kaleidux-common and leveraging Unix Domain Sockets with JSON serialization, the project achieves a clean separation between the high-performance rendering engine and the user interface tools. This design allows for complex automation (via Rhai scripting or CLI tools) while maintaining a robust and typesafe interface.