Both run() and run_new() were starting with Task::none(), so the Bootstrap font was never loaded. All icon() calls in the setup wizard rendered as '?' glyphs. Load the font as the initial task (batched with AutoDownload where needed) and handle FontLoaded as a no-op. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
umutray
Note: This project is entirely vibe-coded by Claude. Every line of Rust, every commit message, and this README were written by an AI working from conversational prompts. Expect the usual caveats.
A small system-tray daemon and CLI for running Windows game launchers on Linux via umu-launcher and GE-Proton.
Ships with presets for six launchers out of the box:
- Battle.net
- EA App
- Epic Games
- Ubisoft Connect
- GOG Galaxy
- Rockstar Games
Each lives in its own Wine prefix and shows up in the tray with per-launcher
Launch / Kill entries. Users can add or remove launchers in config edit.
Features
- Tray icon on any SNI-capable desktop (KDE, GNOME+AppIndicator, Xfce …).
- Per-launcher running state reflected in the tray via a 2 s poller.
update-proton— streams GE-Proton releases straight to disk from GitHub (no ~600 MB in-memory buffering), with a progress indicator.diagnose— sanity-checks umu-run, Vulkan, display server, per-launcher prefix / exe / ownership / running state.service— installs an XDG autostart entry so the tray autostarts with the graphical session.setup— graphical wizard (iced) that downloads an installer URL (with progress bar) or accepts a local.exe, then runs it viaumu-runin the launcher's Wine prefix with a live log pane. Uninstalled launchers expose a Setup… entry directly in the tray.
Install
cargo build --release
install -Dm755 target/release/umutray ~/.local/bin/umutray
Requires umu-launcher, tar, and vulkan-tools on PATH. On Arch:
sudo pacman -S umu-launcher vulkan-tools
Then enable autostart:
umutray service install
Usage
| Command | What it does |
|---|---|
umutray |
Start the tray daemon (default) |
umutray gui |
Open the graphical dashboard (with tray icon) |
umutray launchers |
List configured launchers and their state |
umutray launch <name> |
Launch a specific launcher (e.g. umutray launch epic) |
umutray kill [<name>] |
Kill one launcher, or all if no name is given |
umutray play <launcher> <game> |
Play a game with its configured overlays |
umutray games [<launcher>] |
List configured games and their overlay flags |
umutray diagnose [<name>] |
Health checks (one launcher or all) |
umutray setup <name> |
Open the graphical setup wizard for a launcher |
umutray detect [--apply] |
Scan common Wine prefixes for installed launchers |
umutray update-proton --latest |
Install newest GE-Proton release |
umutray update-proton --list |
Show recent releases without installing |
umutray update-proton |
Interactive version picker |
umutray config show / path |
Print current config or its file path |
umutray config edit |
Open config in $EDITOR |
umutray config set … |
Update globals (--proton-version, --compat-dir) |
umutray config add-launcher … |
Append a new launcher (needs --exe-path) |
umutray config remove-launcher |
Drop a launcher (prefix on disk is left untouched) |
umutray config add-game … |
Attach a game to a launcher (needs --exe-path) |
umutray config remove-game … |
Drop a game from a launcher |
umutray config set-game-flags … |
Per-game overlay toggles: gamemode/mangohud/gamescope |
umutray service install |
Write XDG autostart entry (tray starts on login) |
umutray service uninstall |
Remove the autostart and desktop entries |
umutray service status |
Show whether XDG autostart is enabled |
Config
Lives at ~/.config/umutray/config.toml. A full config looks like:
proton_compat_dir = "/home/you/.local/share/Steam/compatibilitytools.d"
proton_version = "GE-Proton"
[[launchers]]
name = "battlenet"
display = "Battle.net"
prefix_dir = "/home/you/Games/battlenet"
exe_path = "Program Files (x86)/Battle.net/Battle.net Launcher.exe"
gameid = "umu-battlenet"
process_pattern = "Battle\\.net"
# …one [[launchers]] block per launcher
proton_version = "GE-Proton" tells umu-launcher to auto-fetch the latest.
Setting it to a pinned tag (done automatically by update-proton) uses
that specific version. Each launcher may override the global proton_version
with its own.
License
MIT. See LICENSE.