Soundsible Desktop Shell
Tauri consumer wrapper for Soundsible. It uses the official native folder
dialog, supervises the bundled engine, exposes tray controls, and hands the
webview to /player/desktop/.
Dev workflow
Linux deps (once): webkit2gtk-4.1, gtk3, libappindicator-gtk3, librsvg, base-devel
Arch: sudo pacman -S webkit2gtk-4.1 gtk3 libappindicator-gtk3 librsvg base-devel
From repo root, ensure Python deps are installed (venv/ exists).
cd desktop-shell
npm install
export SOUNDSIBLE_REPO_ROOT="$(cd .. && pwd)"
npm run dev
Optional overrides:
SOUNDSIBLE_PYTHON— Python binary (default:venv/bin/python3)SOUNDSIBLE_ENGINE_BIN— PyInstaller sidecar for packaged buildsSOUNDSIBLE_CONFIG_DIR— config directory (default: platformsoundsibleconfig dir)
Architecture
Tauri (Rust) → spawn soundsible_engine.py → poll desktop-engine-state.json
→ health watchdog (3× fail @ 5s) → navigate webview to player
Tray: Open | Pair phone… | Restart engine | Stop engine | Quit
Keyboard (DT5): Global shortcuts work even when the window is hidden:
| Shortcut | Action |
|---|---|
Ctrl+Alt+O | Open / focus main window |
Ctrl+Alt+P | Pair phone (QR + paired device list) |
Ctrl+Alt+R | Restart engine |
Ctrl+Alt+S | Stop engine (returns to shell UI) |
Ctrl+Alt+Q | Quit (stops engine and exits) |
Left-click tray icon also focuses the window. Right-click opens the tray menu (platform convention).
Closing the window hides Soundsible in the tray and keeps playback running.
Use Quit or Ctrl+Alt+Q to stop the engine and exit.
Accessibility
- Shell buttons use 44px minimum touch targets (
DESIGN.mdDT5) :focus-visibleoutline on shell buttons; focus moves to the primary action when switching views (first-run → loading → error)- The webview loads the shared responsive SolidJS player from
/player/desktop/.
Shell source lives in shell-ui/ and Vite writes the untracked
shell-ui-dist/ bundle consumed by Tauri. Player UI is the existing ui_web
bundle served by the sidecar.
Phone pairing (§6)
Native pairing UI in the shell (tray Pair phone… or Ctrl+Alt+P):
- Creates a pairing session via the engine API (owner token on loopback)
- Shows QR code + pairing code + claim URL
- Polls session status until the phone is paired
- Lists paired phones with revoke
Requires the engine to be running (Ready). The web player Settings screen still exposes the same flow for power users.
Build
npm run build
PyInstaller sidecar packaging is tracked separately (eng review 4A). Dev mode runs the repo Python engine directly.
Sidecar build (PyInstaller)
Requires a venv with requirements.txt installed plus librsvg only for icon generation (not the sidecar).
./desktop-shell/scripts/build-sidecar.sh
Bundle a static FFmpeg next to the engine (recommended for release builds):
BUNDLE_FFMPEG=1 ./desktop-shell/scripts/build-sidecar.sh
This runs fetch-ffmpeg.sh, embeds FFmpeg in the sidecar when possible, and places binaries/ffmpeg-<target-triple> for Tauri externalBin. /api/health reports ffmpeg.available.
This writes desktop-shell/src-tauri/binaries/soundsible-engine-<target-triple>, which Tauri bundles via externalBin. The shell prefers the sidecar over repo Python when present.
Windows RC validation: docs/DESKTOP_BETA.md
Release CI: installers ship with the whole product on a v* tag — see docs/RELEASING.md. For a build without a release, run .github/workflows/desktop-build.yml manually.
Sidecar flags used by the shell:
| Flag | Purpose |
|---|---|
--bootstrap MUSIC_DIR | Write consumer config.json before first start |
--music-dir MUSIC_DIR | Runtime library path (also auto-bootstraps if config missing) |
Returning users: if config.json and music_dir.json already exist, the shell skips first-run and auto-starts the engine on launch.
Start at login: optional checkbox on first-run (uses platform autostart APIs via tauri-plugin-autostart).
Smoke test
Headless check for engine health + desktop player route:
./desktop-shell/scripts/smoke-test.sh # Python engine
./desktop-shell/scripts/smoke-test.sh --with-sidecar
./desktop-shell/scripts/smoke-test.sh --with-sidecar --with-tauri
CI runs the same checks in .github/workflows/desktop-shell.yml (Linux + Windows sidecar/Tauri jobs).
Windows sidecars: native runners produce
soundsible-engine-x86_64-pc-windows-msvc.exe and
soundsible-engine-aarch64-pc-windows-msvc.exe. CI verifies that the shell,
engine, and FFmpeg all match the advertised architecture.
Windows RC delivery is NSIS .exe only. Closing the main window hides it to
the tray; Quit stops the engine and exits.
Icons (DT3)
Tray and bundle icons are generated from branding/logo-mark.svg:
./desktop-shell/scripts/generate-icons.sh
Requires rsvg-convert (librsvg) and @tauri-apps/cli.
| Asset | Usage |
|---|---|
src-tauri/icons/tray-idle.png | System tray idle glyph (32×32) |
src-tauri/icons/icon.{ico,icns,png} | App bundle / window icon |
Platform notes:
- Linux: Colored static glyph in AppIndicator tray (VU-meter animation deferred).
- Windows: Multi-size
.icofrom bundle set. - macOS: Colored glyph for v1; template (monochrome menu-bar) icon deferred until VU-meter tray work.