WallpaperMachine
The wallpapers you love. A new home on your Mac.
Per-light control, dynamic scenes, and screen-to-light sync over the official Hue Entertainment API v2. Native Wayland. Open source.
LifestyleHTML · GoGitHub @sebascodeOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Spectra Control is a simple application to control and connect to custom Phillips Hue Lights from Linux.
Taken from the repository README
Loading the full README.
Read the full README ↗Linux desktop app for Philips Hue lights, with screen-to-light sync over the official Hue Entertainment API v2. Fills the gap left by the Hue Sync app, which has no Linux version.
→ Landing page with screenshots: spectracontrol.scode.casa
Tested on Bazzite (Fedora 44 immutable) + GNOME Wayland with NVIDIA. Should also work on KDE Plasma Wayland and any compositor that exposes xdg-desktop-portal Screencast.
Light control
~/.config/spectracontrol/scenes/*.json (override built-ins by id)Screen Sync
xdg-desktop-portal Screencast + GStreamer (pipewiresrc) under Tauri. Bypasses WebKitGTK's broken getDisplayMedia on Wayland.http://localhost:8000 uses getDisplayMedia() for environments without Tauri.Desktop integration
Updates & profile
latest.json via minisign)Internationalization
frontend/i18n/<locale>.json), Spanish and English shipped, language picker on first launch and in Settingsxdg-desktop-portal (KDE or GNOME)generateclientkey: truecargo install tauri-cli (for the desktop app)pipewiresrc (gstreamer1-plugin-pipewire)sudo rpm-ostree install pipewire-devel clang-devel glibc-devel \
wayland-devel libxcb-devel webkit2gtk4.1-devel
sudo rpm-ostree apply-live --allow-replacement # or reboot
# Tauri desktop window (recommended)
cargo tauri dev
# Browser mode — Firefox at http://localhost:8000
./run.sh
run.sh builds and starts the Go backend on :8000. cargo tauri dev does the same automatically via beforeDevCommand.
Chromium-based browsers and the WebKitGTK webview don't deliver frames from
getDisplayMedia()on Wayland. Use Tauri (native portal capture) or Firefox (which uses pipewire correctly).
Pre-built bundles for each tagged release live in GitHub Releases (AppImage, .deb, .rpm). Pick whichever matches your distro.
chmod +x SpectraControl_*_amd64.AppImage
./SpectraControl_*_amd64.AppImage
Needs
libfuse2to mount itself. On modern Fedora that isfuse-libs. As a fallback, run with--appimage-extract-and-run.
sudo dpkg -i SpectraControl_*_amd64.deb # Debian/Ubuntu
sudo rpm -i SpectraControl-*.x86_64.rpm # Fedora/RHEL
The bundles embed the Go backend (spectractl) and the frontend, so no separate install is needed. Config is written to ~/.config/spectracontrol/hue_config.json. User scenes are picked up from ~/.config/spectracontrol/scenes/*.json (override built-ins by id).
./build.sh appimage,deb,rpm
# → src-tauri/target/release/bundle/{appimage,deb,rpm}/
build.sh runs cargo tauri build with NO_STRIP=true, which is required on Fedora 40+ — Fedora's shared libraries use packed relocations (.relr.dyn / DT_RELR) that the strip bundled in linuxdeploy does not recognise.
Updates are driven by the tauri-plugin-updater plugin against a signed latest.json published with every release.
On launch the app GETs https://github.com/sebascode/SpectraControl_App/releases/latest/download/latest.json. If the published version is newer than the running one, a banner appears at the top of the window with Actualizar / Update. Clicking it:
.AppImage, verifies it against the minisign signature compiled into the binary, and atomically replaces the file on disk.A manual "Chequear actualizaciones" button is available in Settings → Acerca de, with explicit feedback ("Estás en la última versión", error toasts, etc.).
.deb / .rpm users don't get in-place install — re-download and run your package manager.
CI builds and publishes on tag push. To cut a release:
# bump src-tauri/Cargo.toml and tauri.conf.json to the new version first
git commit -am "chore: bump version to 0.2.X"
git tag v0.2.X
git push origin master v0.2.X
.github/workflows/release.yml then:
ubuntu-22.04, injecting the version into the Go binary via -ldflags "-X main.Version=$SPECTRA_VERSION".latest.json + .AppImage.sig.SHA256SUMS + latest.json to the GitHub Release for that tag.You can dry-run the build (no publish) from the Actions tab → Release → Run workflow.
Pre-releases: tag with a suffix like v0.2.8-beta1 and GitHub marks the release as prerelease. The default updater endpoint (releases/latest/download/latest.json) only resolves to the most recent stable, so users on stable will not see beta releases.
client_key (PSK for DTLS).~/.config/spectracontrol/hue_config.json.If the client_key is missing (older pairings without generateclientkey), re-pair from the setup screen — Entertainment streaming requires it.
For a set-and-forget setup, enable Iniciar con el sistema + Iniciar Screen Sync al arrancar in Settings → Apariencia. The app launches at login, picks up the last used entertainment area, and starts syncing without a single click.
The capture pipeline downscales the screen to 320×180 RGB in GStreamer, so sampling stays cheap regardless of display resolution. The bridge receives ~30 fps of color updates per channel via DTLS.
| Layer | Tech |
|---|---|
| Backend | Go · chi · gorilla/websocket · pion/dtls |
| Frontend | Vanilla HTML/CSS/JS (single file, no bundler) |
| Desktop shell | Tauri 2 (Rust) |
| Screen capture (Tauri) | ashpd (xdg-desktop-portal Screencast) + gst-launch-1.0 (pipewiresrc → videoscale → fdsink) |
| Screen capture (browser) | getDisplayMedia() |
| Hue API v1 | Local REST (lights, groups, config) |
| Hue API v2 (CLIP) | HTTPS (entertainment configs, application id) |
| Entertainment streaming | UDP/DTLS · HueStream v2 · bridge port 2100 |
| Updates | tauri-plugin-updater + signed latest.json (minisign) |
| i18n | File-based JSON dictionaries loaded at runtime |
SpectraControl/
├── backend/
│ ├── main.go ← HTTP routes, WebSocket, color conversion
│ ├── entertainment.go ← DTLS streaming, CLIP v2, HueStream packet builder
│ ├── scenes.go ← dynamic scene runner (JSON-loaded presets)
│ ├── scenes/*.json ← built-in scene presets (embedded via go:embed)
│ ├── brightness.go ← global brightness state, applied to sync + scenes
│ └── go.mod / go.sum
├── frontend/
│ ├── index.html ← entire UI
│ └── i18n/*.json ← translations (one file per locale)
├── src-tauri/
│ ├── src/main.rs ← spawns Go backend, runs ashpd + gst capture, tray, autostart
│ ├── capabilities/ ← Tauri permission grants per plugin
│ ├── Cargo.toml
│ └── tauri.conf.json
├── docs/ ← Hue API v2 reference (offline copy)
├── run.sh ← build + run the Go backend standalone
└── build.sh ← build the AppImage (release)
The active backlog lives in GitHub Project #4 — SpectraControl Roadmap. Highlights coming next:
cargo tauri dev terminal for [capture] logs. In browser mode, only Firefox works on Wayland.client_key missing — re-pair from the setup screen. Required for Entertainment v2 (DTLS PSK).libgbm or mesa-libgbm-devel — these come from xcap / libwayshot-xcap. SpectraControl doesn't use them; if a cargo build complains, re-check Cargo.toml deps match the current tree.spectractl and spectra-control processes and relaunch.NO_STRIP=true on Fedora 40+ (handled automatically by build.sh); other distros may not need it.See CONTRIBUTING.md for dev setup, repo layout, commit conventions, and the release flow. Issues and PRs welcome.
MIT — see LICENSE.