Browse documentation
Documentation for v0.14.0View original source ↗

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 builds
  • SOUNDSIBLE_CONFIG_DIR — config directory (default: platform soundsible config 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:

ShortcutAction
Ctrl+Alt+OOpen / focus main window
Ctrl+Alt+PPair phone (QR + paired device list)
Ctrl+Alt+RRestart engine
Ctrl+Alt+SStop engine (returns to shell UI)
Ctrl+Alt+QQuit (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.md DT5)
  • :focus-visible outline 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:

FlagPurpose
--bootstrap MUSIC_DIRWrite consumer config.json before first start
--music-dir MUSIC_DIRRuntime 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.

AssetUsage
src-tauri/icons/tray-idle.pngSystem 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 .ico from bundle set.
  • macOS: Colored glyph for v1; template (monochrome menu-bar) icon deferred until VU-meter tray work.

Search documentation