Mouse not required This is done by sending StopCommand to shepherdd, not by natively closing the window. Sway initiates this to avoid any issues with shepherd-launcher not having focus (as it won't when an activity is running). |
||
|---|---|---|
| .. | ||
| src | ||
| Cargo.toml | ||
| README.md | ||
shepherd-launcher-ui
Main launcher grid interface for Shepherd.
Overview
shepherd-launcher-ui is the primary user-facing shell for the Shepherd kiosk environment. It presents a grid of available entries (applications, games, media) and allows users to launch them.
This is what users see when no session is active—the "home screen" of the environment.
Features
- Entry grid - Large, touch-friendly tiles for each available entry
- Availability display - Visual indication of enabled/disabled entries
- Launch requests - Send launch commands to the service
- State synchronization - Always reflects service's authoritative state
Architecture
┌───────────────────────────────────────────────────────┐
│ Sway / Wayland Compositor │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Launcher UI (fullscreen) │ │
│ │ │ │
│ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │Minecraf│ │GCompris│ │ Movies │ │ Books │ │ │
│ │ │ │ │ │ │ │ │ │ │ │
│ │ └────────┘ └────────┘ └────────┘ └────────┘ │ │
│ │ │ │
│ │ ┌────────┐ ┌────────┐ │ │
│ │ │ │ │ │ │ │
│ │ │ ScummVM│ │Bedtime │ │ │
│ │ │ │ │ │ │ │
│ │ └────────┘ └────────┘ │ │
│ │ │ │
│ └──────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────┘
Usage
Running
# With default socket path
shepherd-launcher
# With custom socket path
shepherd-launcher --socket /custom/path/shepherdd.sock
Command-Line Options
| Option | Default | Description |
|---|---|---|
-s, --socket |
$XDG_RUNTIME_DIR/shepherdd/shepherdd.sock |
Service socket path |
-l, --log-level |
info |
Log verbosity |
Grid Behavior
Entry Tiles
Each tile displays:
- Icon - Large, recognizable icon
- Label - Entry name
- Status - Enabled (bright) or disabled (dimmed)
- Time indicator - Max duration if started now (e.g., "30 min")
Enabled Entries
When an entry is enabled:
- Tile is fully visible and interactive
- Tapping sends
Launchcommand to service - Grid shows "Launching..." state
- On success: launcher hides, application starts
Disabled Entries
When an entry is disabled it is not displayed.
Launch Flow
User taps tile
│
▼
Launcher sends Launch command
│
▼
Grid input disabled
"Starting..." overlay shown
│
▼
┌─────┴─────┐
│ │
▼ ▼
Success Failure
│ │
▼ ▼
Launcher Error message
hides Grid restored
State Management
The launcher maintains a reactive state model:
struct LauncherState {
entries: Vec<EntryView>, // From service
current_session: Option<SessionInfo>,
connected: bool,
launching: Option<EntryId>,
}
Event Handling
| Event | Launcher Response |
|---|---|
StateChanged |
Update entry grid |
SessionStarted |
Hide launcher |
SessionEnded |
Show launcher |
PolicyReloaded |
Refresh entry list |
Visibility Rules
The launcher is visible when:
- No session is running, OR
- User explicitly returns to home (via HUD)
The launcher hides when:
- A session is actively running
- (Fullscreen app is in front)
Error Handling
Service Unavailable
If the service is not running at startup:
┌────────────────────────────────────────┐
│ │
│ System Not Ready │
│ │
│ Waiting for shepherd service... │
│ │
│ [Retry] │
│ │
└────────────────────────────────────────┘
Launch Failure
If launching fails:
- Error notification appears
- Grid is restored to interactive state
- User can try again or choose another entry
Connection Loss
If connection to service is lost:
- Entries become disabled
- Reconnection attempted automatically
- State refreshed on reconnection
Accessibility
- Touch-first - Large touch targets (minimum 44px)
- High contrast - Clear visual hierarchy
- Minimal text - Icon-first design
- Keyboard navigation - Arrow keys and Enter
- No hover-only interactions - All actions accessible via tap
Styling
The launcher uses a child-friendly design:
- Large, colorful icons
- Rounded corners
- Clear enabled/disabled distinction
- Smooth transitions
- Dark background (for contrast)
Dependencies
gtk4- GTK4 bindingstokio- Async runtimeshepherd-api- Protocol typesshepherd-ipc- Client implementationclap- Argument parsingtracing- Logging
Building
cargo build --release -p shepherd-launcher-ui
The resulting binary is named shepherd-launcher.
Relationship to Service
Critical: The launcher is purely a presentation layer. It:
- Displays what the service allows
- Sends launch requests
- Shows service state
It does not:
- Tracks time independently
- Decide availability
- Enforce policy
If the launcher crashes, the service continues enforcement. If the launcher is replaced, the system still works.