# Desktop Designer
The desktop designer (`designer/`) provides rapid UI development with:
- **Hot-reload**: Automatically reloads when RML/RCSS/Lua files change
- **Shell Mode**: Persistent system UI (status bar, nav bar) with apps loading into container
- **UI Hierarchy Dumping**: Exports element tree to JSON for inspection
- **Screenshot Capture**: PNG export via F12 key
- **Logging**: Detailed output for debugging navigation and events
- **Action Recording**: Record mouse/keyboard interactions to JSON
- **Action Playback**: Replay recorded interactions with timing
## Key Files
| File | Purpose |
|------|---------|
| `designer/main.cpp` | Main entry point, GLFW window, event loop |
| `designer/src/desktop_sandbox.cpp` | Per-app sandbox isolation |
| `designer/src/app_discovery.cpp` | Scans directories for app manifests |
| `designer/src/testing/ui_inspector.cpp` | UI hierarchy JSON export |
| `designer/src/testing/visual_capture.cpp` | PNG screenshot capture |
| `designer/src/testing/action_recorder.cpp` | Record user interactions |
| `designer/src/testing/action_player.cpp` | Playback recorded actions |
## Command Line Options
```
General:
--resolution WxH Set window resolution (default: 540x960)
--assets PATH Set assets directory (default: derived from document)
--log FILE Write all log messages to file
--hierarchy FILE Continuously dump UI hierarchy to JSON
Simulator mode:
--simulator Run in simulator mode (uses shell by default)
--no-shell Disable shell (use direct document loading)
--test-apps PATH Path to test-apps directory (default: ./base-apps)
Test modes:
--record FILE Record user actions to JSON file
--playback FILE Playback actions from JSON file
--screenshot FILE Take screenshot and exit
--dump-hierarchy FILE Dump UI hierarchy to JSON and exit
```
## Running the Designer
### Simulator Mode with Shell (Recommended)
```bash
cd MosisService
./designer/build/Release/mosis-designer.exe --simulator --test-apps base-apps
```
This will:
- Load the **system shell** with persistent status bar and navigation bar
- Load home screen content into the shell's app container
- Scan `base-apps/` for apps with valid `manifest.json`
- Enable app navigation with proper back button support
### Simulator Mode without Shell
To test the old direct-document approach:
```bash
./designer/build/Release/mosis-designer.exe --simulator --test-apps base-apps --no-shell
```
### Direct Document Mode
To load a specific RML document directly:
```bash
./designer/build/Release/mosis-designer.exe path/to/document.rml
```
## Keyboard Controls
| Key | Function |
|-----|----------|
| F5 | Reload document / Start-stop recording |
| F12 | Toggle RmlUi debugger |
| ESC | Back navigation |
| R | Start/Stop recording (in interactive mode) |
---
## Shell Architecture
The shell (`apps/shell/`) provides a persistent system UI layer that prevents apps from taking over the full screen.
### Shell Components
```
┌──────────────────────────────┐
│ Status Bar (36px) │ ← Time, WiFi, Signal, Battery
├──────────────────────────────┤
│ │
│ App Container │ ← App content loads here
│ (flex: 1) │
│ │
├──────────────────────────────┤
│ Navigation Bar (56px) │ ← Back, Home, Recents
└──────────────────────────────┘
Overlay Layers (z-index order):
- Dialog overlay (z: 600) ← Modal dialogs
- Toast container (z: 500) ← Toast notifications
- Notification panel (z: 400) ← Pull-down notifications
- Loading overlay (z: 300) ← App loading spinner
```
### Shell Files
| File | Purpose |
|------|---------|
| `apps/shell/shell.rml` | Shell document with status bar, nav bar, overlays |
| `apps/shell/shell.lua` | Navigation, toasts, dialogs, notifications |
### App Content Fragments
Apps in shell mode use **content fragments** (`*_content.rml`) instead of full documents:
```rml
```
### Shell Lua API
Functions available to apps via shell:
```lua
-- Navigation
shellNavigateTo("settings") -- Navigate to system app
shellLaunchApp(id, path, entry) -- Launch external app
shellGoBack() -- Go to previous app
shellGoHome() -- Go to home (clear history)
-- UI Feedback
showToast("Message") -- Show toast notification
showToast("Error!", "error") -- Toast types: default, success, error, warning
showDialog("Title", "Message", onConfirm, onCancel)
-- Notifications
addNotification("Title", "Text", icon, app_id)
toggleNotifications() -- Show/hide notification panel
clearNotifications()
```
### Creating Content Fragments
1. Create `appname_content.rml` (not a full document)
2. Include styles via `
```
### Content Fragment Locations
| App | Content Fragment Path |
|-----|----------------------|
| Home | `apps/home/home_content.rml` |
| Camera | `apps/camera/camera_content.rml` |
| Dialer | `apps/dialer/dialer_content.rml` |
| Messages | `apps/messages/messages_content.rml` |
| Browser | `apps/browser/browser_content.rml` |
| Settings | `apps/settings/settings_content.rml` |
| Music | `apps/music/music_content.rml` |
| Store | `apps/store/store_content.rml` |
| Contacts | `apps/contacts/contacts_content.rml` |
---
## Hot Reload
The designer watches for file changes in the assets directory:
- **RML files**: Reloads document
- **RCSS files**: Reloads stylesheets
- **Lua files**: Reloads scripts
- **TGA/PNG files**: Reloads textures
Press F5 to force reload.
## UI Hierarchy Dump
Use `--hierarchy` to continuously dump the UI element tree:
```bash
./designer/build/Release/mosis-designer.exe --simulator --hierarchy ui_tree.json
```
The JSON contains element bounds, classes, IDs, and visibility - useful for automated testing.
## Action Recording and Playback
See [TESTING-FRAMEWORK.md](TESTING-FRAMEWORK.md) for details on recording and playing back UI interactions.
---
## Known Issues and Workarounds
### RmlUi Layout Breaking Due to File Encoding
**Problem**: Content fragments created with certain file-writing methods may render with broken layouts - elements appear with 0 width, text wraps excessively, and flex layouts collapse.
**Symptoms**:
- List items don't expand to full width
- Text wraps to very narrow columns
- Avatars/icons overlap with text
- UI hierarchy shows `"width": 0.0` for elements that should have proper width
**Root Cause**: RmlUi's parser is sensitive to certain invisible file formatting. While files may appear identical in text editors and have the same line endings (CRLF), subtle encoding differences can break layout parsing.
**Diagnosis**: Use `--hierarchy FILE` flag to dump UI element dimensions:
```bash
./designer/build/Release/mosis-designer.exe --simulator --playback tests/test_app.json --hierarchy hierarchy.json
```
Check the JSON for elements with `"width": 0.0` that should have proper dimensions.
**Workaround**: Instead of creating content fragments from scratch, copy an existing working file and modify it:
```bash
# 1. Copy a known working file (e.g., messages_content.rml)
cp src/main/assets/apps/messages/messages_content.rml src/main/assets/apps/myapp/myapp_content.rml
# 2. Edit the file incrementally (use sed, text editor, or Edit tool)
# DO NOT rewrite the entire file - preserve the original byte structure
# 3. Test the layout
./designer/build/Release/mosis-designer.exe --simulator --playback tests/test_myapp.json --screenshot-after test.png
```
**Working Reference Files**:
- `apps/messages/messages_content.rml` - Known good file format
- `apps/store/store_content.rml` - Created by copying from messages
- `apps/settings/settings_content.rml` - Created by copying from messages
**Prevention**: When creating new content fragments:
1. Always start by copying an existing working content fragment
2. Make incremental edits rather than full file rewrites
3. Test layout after changes using `--hierarchy` flag