Commit Graph

33 Commits

Author SHA1 Message Date
funman300 32c6e1fce0 setup: auto-download official installer for existing launchers too 2026-04-19 00:40:04 -07:00
funman300 20509fb488 gui: transition to tray on close, auto-download official installers in setup 2026-04-19 00:36:22 -07:00
funman300 f645b58470 chore(settings): remove self-update / Rebuild & Install feature
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 23:52:07 -07:00
funman300 9ad1e6a745 refactor(setup): complete UX overhaul of the install wizard
- Step indicator (1→2→3) on both screens showing current position
- Fixed window size (520×440, non-resizable) for consistent presentation
- view_install redesigned with card-based layout matching view_picking
- Status messages colour-coded: blue=info, green=success, red=error
- Official installer shown as a badge ("✓ Official installer") — URL hidden
- Download/install progress in a styled card with byte counter
- Finished state has distinct success (green border) / failure (red border) banners
- Installation log collapsed by default behind "Show details ▼" toggle
- Removed "via umu-run" and other internal tool references from user-facing text
- Removed raw "Paste a URL…" initial status — context is clear from the card
- Window title simplified to "umutray — <Launcher Name>"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 23:49:36 -07:00
funman300 f70498158a feat(settings): add Rebuild & Install self-update button
Settings panel now shows the current version and a "Rebuild & Install
Latest" button that:
  1. git pull from the embedded source directory (CARGO_MANIFEST_DIR)
  2. makepkg -sf in packaging/
  3. pkexec pacman -U (graphical polkit auth prompt)

Reports the installed version on success; surfaces the failing step on
error. Update runs off the UI thread so the window stays responsive.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 23:41:07 -07:00
funman300 3c78e1586f refactor(setup): redesign launcher picking screen
Replaced the flat form layout with a polished card-based design:
- Section cards with subtle borders matching the dashboard style
- Blue accent labels for section headings (Launcher, Install Location)
- Hint text explaining the Wine prefix folder
- Error status styled in orange-red instead of plain text
- Next button right-aligned with top spacing
- Header with muted subtitle

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 23:37:26 -07:00
funman300 0c22e23ad3 fix(gui): load Bootstrap Icons font via Task instead of builder
The .font() builder method was silently failing to register the font
for named lookup. Using iced::font::load() as a startup Task ensures
the font is properly loaded before any text rendering occurs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 23:34:22 -07:00
funman300 108f385973 fix(gui): correct Bootstrap Icons codepoint for gear icon
Font version in iced_fonts 0.1.1 maps GearFill to U+F3E2, not U+F3F8.
Using the wrong codepoint rendered as a question-mark placeholder.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 23:28:12 -07:00
funman300 d97a13e289 chore(packaging): remove systemd service from PKGBUILD, bump pkgrel
The app now uses XDG autostart (~/.config/autostart/umutray.desktop)
managed via the Settings panel, not systemd. The service file is no
longer installed by the package.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 23:24:12 -07:00
funman300 2e51b2e788 refactor(ui): cleaner setup wizard and dashboard card visuals
- setup.rs: remove raw prefix/expected path labels from install view;
  hide URL input when official installer is pre-filled (show green tick
  instead), revealing an override field only when needed
- gui.rs: drop raw exe path from scan result rows; add per-state colour
  to status indicator (green=running, blue=installed, grey=not installed)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 23:19:30 -07:00
funman300 c4587b0729 fix: downgrade iced_fonts to 0.1 for iced 0.13 compatibility
iced_fonts 0.3 pulls in iced_widget 0.14 / iced_renderer 0.14 which
breaks release builds when used alongside iced 0.13. Pin to 0.1.x
which targets iced 0.12/0.13 and drop the unused iced_aw dependency.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 23:12:52 -07:00
funman300 d4f0515a82 refactor(setup): clean up setup wizard UX
- Hide raw filesystem paths from all status messages; use launcher
  display names instead (e.g. "Downloading Battle.net installer…")
- Simplify installer source label: show "✓ Official installer detected"
  badge when URL is auto-filled
- Replace separate "Download / Prepare" + "Run installer" buttons with
  a single context-aware action button whose label tracks the stage:
  Download → / Downloading… / Install → / Installing…
- Remove auto-download on launcher confirm; show confirmation prompt
  "Ready to download the official X installer. Press Download → to begin."
- Soften the exe-not-found error message; remove raw path and config
  editing advice — direct users to the log instead
- Rename "Launch now" → "Open launcher" for clarity
- Show "✓ X installed successfully!" success banner above Close/Open
  buttons when install completes and the exe is present

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 23:06:32 -07:00
funman300 156bb460a0 feat(gui): replace settings ⚙ placeholder with Bootstrap cog icon
Add iced_aw + iced_fonts (bootstrap feature) to load the Bootstrap Icons
font. The settings button and settings header now render the gear-fill
glyph (U+F3F8) via text("\u{F3F8}").font("bootstrap-icons") instead of
the raw ⚙ character which was not in iced's bundled Inter font.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 23:06:22 -07:00
funman300 9134d3bab0 feat(gui): auto-detect games in Wine prefix and browse for exe
- detect::scan_games_in_prefix() walks drive_c/Program Files and
  Program Files (x86) up to depth 4, skipping Windows system dirs,
  the launcher's own exe, and already-configured games
- Empty game list now shows "No games added yet." with two actions:
    · Scan for games — async scan of the Wine prefix, results appear
      as a clickable list with + buttons to add each found exe
    · Browse exe… — native file picker (zenity/kdialog) opening in
      drive_c/, computes the relative path automatically
- Add-game form gains a Browse… button to pick exe from the prefix
- util::pick_file() added alongside pick_folder()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 19:50:48 -07:00
funman300 74f21b6b75 fix(setup): add Close and Launch Now buttons after install completes
The wizard previously reached Stage::Finished and showed a status
message with no way to proceed — the user was stuck. Now:

- A Close button exits the setup window
- A Launch Now button (enabled only when the exe exists) launches
  the newly installed launcher and closes the wizard

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 19:43:55 -07:00
funman300 05a12b7cee chore: remove Makefile in favour of packaging/PKGBUILD
The PKGBUILD in packaging/ covers everything the Makefile did.
Local installs should use `cd packaging && makepkg -si` instead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 19:37:43 -07:00
funman300 f170171895 feat: GUI dashboard, system Proton scanning, and XDG autostart
GUI dashboard (gui.rs):
- Add detect, diagnose, settings panel, per-launcher games management
- Async Kill with optimistic UI state and rollback on error
- Settings: pick_list for Proton version, browse button for compat dir,
  validation, per-launcher version badge
- Detect Installed button with scan results in footer
- Diagnose card with ✓/✗ checklist per launcher

Issue #1 — Use System Proton (proton.rs):
- Extend list_installed() to scan ~/.steam/root/compatibilitytools.d,
  ~/.local/share/Steam/compatibilitytools.d, and
  /usr/share/steam/compatibilitytools.d in addition to the configured
  compat dir; deduplicates by name so the same version never appears twice

Issue #4 — Remove Systemd Service (service.rs):
- Replace systemd unit management with XDG autostart:
  install() writes ~/.config/autostart/umutray.desktop instead of a
  systemd unit and never calls systemctl; uninstall() removes that file;
  status() checks whether the autostart entry exists
- Update GUI service_is_installed() to check the XDG autostart path

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 19:28:22 -07:00
funman300 9b7e474e80 refactor: apply CLAUDE.md code quality improvements and add packaging
- Add #![forbid(unsafe_code)] to main.rs (issue #3)
- Replace raw ANSI escape codes with owo-colors crate (issue #2)
- Replace manual HOME path construction with dirs::home_dir() (issue #5)
- Ship umutray.service as a static file; service::install() substitutes
  the binary path at install time instead of generating the unit at runtime
- Add packaging/PKGBUILD following Arch Rust package guidelines
- Add CLAUDE.md tracking refactor tasks
- setup.rs: clean up downloaded temp files on abort/back, save launcher
  to config only after successful install, auto-start download when a
  preset has an installer_url
- util.rs: add pick_folder() using zenity/kdialog subprocesses (no rfd)
- config.rs: populate installer_url for all 6 built-in presets with
  official download URLs
- Document the Option<Option<Vec<String>>> gamescope pattern at main.rs:307

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 19:28:10 -07:00
funman300 f2f584febf new file: Makefile
new file:   TODO.md
	modified:   src/config.rs
	modified:   src/detect.rs
	modified:   src/diagnose.rs
	new file:   src/gui.rs
	modified:   src/main.rs
	modified:   src/service.rs
	modified:   src/setup.rs
	modified:   src/tray.rs
	new file:   src/util.rs
	new file:   umutray.desktop
2026-04-17 23:12:47 -07:00
funman300 4c918e673b Note in README that the project is vibe-coded by Claude
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-17 21:41:47 -07:00
funman300 1bacf345f0 Apply rustfmt pass across all modules
Pure whitespace normalization — no logic changes. Mostly:
- collapsing multi-line match/if arms rustfmt prefers inline
- inlining short `with_context`/`ok_or_else` closures
- reformatting nested method chains for consistency

Build and clippy stay clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-17 21:35:27 -07:00
funman300 e72ee69c14 Add detect command to find installed launchers on disk
Scans common Wine prefix locations (~/Games, ~/.wine, Lutris, Bottles,
Heroic) plus any user-supplied --dir paths for each configured
launcher's exe. Reports matches with four markers:

  ✓ already configured at that prefix
  → detected at a different prefix (--apply to update)
  ⚠ multiple prefixes match (ambiguous)
  · not found

--apply writes the new prefix_dir back to config.toml for unambiguous
cases; ambiguous ones are skipped with a note to resolve via
`config edit`. The Setup doc comment is also refreshed since the iced
wizard landed in an earlier commit.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-17 21:33:48 -07:00
funman300 b72c642223 Add per-game overlay toggles (gamemode, mangohud, gamescope)
Games live under each Launcher as a Vec<Game>; the launcher itself
never picks up overlays, only games launched through `play` do.

- config: Game struct with gamemode/mangohud/gamescope fields, plus
  add_game / remove_game / set_game_flags methods.
- launcher::play_game wraps the game command as
  `gamescope [args] -- gamemoderun umu-run <exe>` (each layer optional)
  and sets MANGOHUD=1 when enabled.
- CLI: `play`, `games`, `config add-game`, `config remove-game`,
  `config set-game-flags`.
- tray: per-game submenus with Play + checkmark toggles for GameMode /
  MangoHud / Gamescope; toggles persist to disk immediately.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-17 17:24:55 -07:00
funman300 22fa1efabf Add setup tray entry, wizard progress/log, config add/remove, stale-wine check
- tray: uninstalled launchers now show a "Setup…" entry that spawns
  the setup wizard as a child process.
- setup.rs: download shows a progress bar (bytes / total), and
  umu-run stdout+stderr stream into a scrollable log pane. A 250 ms
  tick subscription pulls updates from the shared state.
- config add-launcher / remove-launcher CLI, with sensible defaults
  for prefix_dir, gameid, and process_pattern derived from name/exe.
- diagnose: flag stale wineserver processes when no launcher is
  running, suggesting `umutray kill`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-17 12:46:47 -07:00
funman300 14eccf4ef0 Replace setup CLI stub with iced-based wizard
Lets the user paste an installer URL or local .exe path, downloads to
a temp file if needed, and runs the installer via umu-run with the
launcher's prefix, gameid, and proton path wired up. On completion,
checks for the expected exe and reports next steps.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-17 12:39:09 -07:00
funman300 7e5ed3d447 modified: README.md
modified:   src/config.rs
	modified:   src/diagnose.rs
	modified:   src/launcher.rs
	modified:   src/main.rs
	new file:   src/setup.rs
	modified:   src/tray.rs
2026-04-16 21:43:58 -07:00
funman300 336c5d908e Add MIT LICENSE and crates.io metadata
Sets license, readme, repository, keywords and categories so cargo
publish / cargo install pick up the right info. Repo URL points at
the real git.aleshym.co remote.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 17:33:12 -07:00
funman300 6fe558ad00 Rename project: battlenet-manager → umutray
Binary, crate, clap app name, ksni tray id, HTTP user-agent, systemd unit,
XDG config dir (co.aleshym/umutray), README, and all log prefixes.

Config path changes from ~/.config/battlenet-manager/ to ~/.config/umutray/.
Existing users should `mv` the old directory if they've customised it;
otherwise defaults get rewritten on next run.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 17:28:13 -07:00
funman300 f7738d215b Add config and service subcommands
config subcommand — show, path, edit ($EDITOR), and a non-interactive
set that takes --prefix / --compat-dir / --gameid. Lets users retarget
the Wine prefix without hand-editing TOML.

service subcommand — install / uninstall / status for a systemd --user
unit that autostarts the tray. install writes ~/.config/systemd/user/
battlenet-manager.service with ExecStart pointing at the current binary,
then daemon-reloads and enable --now's the unit. uninstall tears it back
down.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 17:25:48 -07:00
funman300 8908c15974 Add download progress and graceful tray shutdown
- proton: wrap the download sink in a small ProgressWriter that prints
  percent / MiB to stderr every 1 MiB so the ~600 MB GE-Proton pull isn't
  silent for minutes. No extra deps.
- tray: store the ksni Handle on the tray itself so Quit can call
  shutdown() before exit(), unregistering the SNI item from D-Bus instead
  of leaving a stale entry until the session bus notices the PID is gone.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 17:21:15 -07:00
funman300 7de6f6d938 Fix launcher/download bugs, add README and Cargo.lock
- launcher: set PROTONPATH to full install path for pinned Proton versions;
  the raw tag name doesn't resolve when umu-run looks it up.
- proton: stream GE-Proton tarballs straight to disk instead of buffering
  ~600 MB in RAM via .bytes(); add error_for_status() on all HTTP calls so
  rate limits and 404s surface clearly; avoid UTF-8 trap on tar args.
- config: fail loudly when $HOME is unset instead of silently writing a Wine
  prefix under /tmp.
- diagnose: replace stat+id shell-out with MetadataExt::uid().
- tray: grab handle() before spawn() consumes the service (the repo didn't
  compile against ksni 0.2 as shipped).
- launcher/diagnose: escape the dot in "battle.net" pgrep patterns so the
  match doesn't false-positive on our own "battlenet-manager" binary; pipe
  pgrep/pkill stdio to /dev/null so PID lists don't leak into our output.
- proton: handle empty release list in pick_interactively cleanly.
- Add README, .gitignore, and commit Cargo.lock for reproducible builds.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 17:18:54 -07:00
funman300 246ad03266 first commit 2026-04-16 13:32:19 -07:00
funman300 1559ee5f2b Initial commit: battlenet-manager tray daemon and CLI 2026-04-16 13:28:17 -07:00