Technology Stack
- Framework: Compose Multiplatform for Desktop
- Language: Kotlin (JVM target)
- Build tool: Gradle with Kotlin DSL
- UI paradigm: Declarative, reactive composition
- Concurrency: Kotlin Coroutines
Project Structure
Application Entry Point
TheMain.kt file is the application’s starting point and implements critical security checks:
Root Detection
The application refuses to start if running as root:KvandClient: Backend Communication
TheKvandClient is a singleton that manages the lifecycle and communication with the backend daemon.
Daemon Launch Process
Why Extract to /tmp?
JVM limitation explained in the code comments:There is a limitation of the JVM in which we CANNOT run executables from inside JAR files, so we have to copy the backend executable into /tmp give it +x permissions and then run it.
Synchronized Command Sending
All communication is synchronized to prevent race conditions:@Synchronized annotation ensures thread-safe access when multiple UI components send commands concurrently.
Error Handling
If the backend fails to start (e.g., user cancels password prompt):UI Architecture
App Composable
The rootApp composable manages application-wide state:
PowerProfiler Component
Example of a hardware control component with coroutines:Key Patterns
- LaunchedEffect for initialization - Fetches current hardware state on component mount
- Dispatchers.IO for blocking operations - Moves network/IO calls off the UI thread
- Loading states - Shows
CircularProgressIndicatoruntil initialization completes - Separate effects for reads and writes - One
LaunchedEffectfor initial read, another watches for user changes
State Management
KVantage uses Compose’s built-in state management:Remember and MutableState
Persistent Settings
Settings are saved to disk usingSettingsManager:
Coroutines and Concurrency
Why Dispatchers.IO?
AllKvandClient.sendCommand() calls are wrapped in withContext(Dispatchers.IO):
- IPC communication with backend process
- Reading/writing to stdin/stdout
- Waiting for ACPI operations
LaunchedEffect for Side Effects
Compose usesLaunchedEffect to trigger coroutines in response to state changes:
pendingUpdate changes, sending the command and resetting the trigger.
Theme System
KVantage includes multiple built-in themes:- Material (Light/Dark)
- Dracula
- Kanagawa
- Whispering Sea
Theme State Management
Animated Background
Optional animated gradient background:Build Configuration
The project uses Gradle with Kotlin DSL:Key Dependencies
- compose.desktop.currentOs - Platform-specific Compose Desktop runtime
- kotlinx.coroutinesSwing - Swing integration for coroutines (used for dialogs)
- kotlinx.json.serializer - JSON serialization for settings
First-Run Experience
The application includes an embedded installer that runs on first launch:~/.local/bin/) and optionally creates desktop entries.
Logging
TheAppLogger utility provides structured logging: