From 20509fb48835d0aea8c03f6a03dcbca27c837976 Mon Sep 17 00:00:00 2001 From: funman300 Date: Sun, 19 Apr 2026 00:36:22 -0700 Subject: [PATCH] gui: transition to tray on close, auto-download official installers in setup --- packaging/PKGBUILD | 14 +++++------ src/main.rs | 7 +++++- src/setup.rs | 63 ++++++++++++++++++++-------------------------- 3 files changed, 40 insertions(+), 44 deletions(-) diff --git a/packaging/PKGBUILD b/packaging/PKGBUILD index e1d9f1b..a2ca8c1 100644 --- a/packaging/PKGBUILD +++ b/packaging/PKGBUILD @@ -12,7 +12,7 @@ pkgname=umutray pkgver=0.1.0 -pkgrel=2 +pkgrel=4 pkgdesc='Tray-based Wine launcher manager for Linux via umu/Proton-GE' arch=('x86_64') url='https://git.aleshym.co/funman300/umutray' @@ -48,13 +48,13 @@ build() { package() { cd "$pkgname" - # Binary - install -Dm755 target/release/umutray "$pkgdir/usr/bin/umutray" + # Binary — install to ~/.local/bin for user-local usage + install -Dm755 target/release/umutray "${HOME}/.local/bin/umutray" - # App menu entry (.desktop uses /usr/bin/umutray as the exec path) - install -Dm644 umutray.desktop "$pkgdir/usr/share/applications/umutray.desktop" - sed -i "s|Exec=umutray|Exec=/usr/bin/umutray|" \ - "$pkgdir/usr/share/applications/umutray.desktop" + # App menu entry for the current user + install -Dm644 umutray.desktop "${HOME}/.local/share/applications/umutray.desktop" + sed -i "s|Exec=umutray|Exec=${HOME}/.local/bin/umutray|" \ + "${HOME}/.local/share/applications/umutray.desktop" # License install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE" diff --git a/src/main.rs b/src/main.rs index 158e7eb..447431e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -321,7 +321,12 @@ fn main() -> Result<()> { } }, - Commands::Gui => gui::run(&config)?, + Commands::Gui => { + gui::run(&config)?; + // After the GUI window closes, continue into the system tray. + let config = config::Config::load().unwrap_or(config); + tray::run(&config)?; + } Commands::Detect { dir, apply } => { detect::run(&config, &dir, apply)?; diff --git a/src/setup.rs b/src/setup.rs index 542a5b1..3cd2575 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -171,16 +171,31 @@ fn update(state: &mut State, message: Message) -> Task { preset.prefix_dir = PathBuf::from(&prefix); // If we know the official installer URL, pre-fill source and - // let the user confirm before downloading. + // start the download automatically. if let Some(url) = preset.installer_url.clone() { - state.source = url; - state.stage = Stage::Idle; - state.status = format!( - "Ready to download the official {} installer. Press Download → to begin.", - preset.display - ); + state.source = url.clone(); state.launcher = Some(preset); - return Task::none(); + state.stage = Stage::Busy; + let display_name = state + .launcher + .as_ref() + .map(|l| l.display.clone()) + .unwrap_or_else(|| "installer".to_string()); + state.status = format!("Downloading {} installer…", display_name); + if let Ok(mut p) = state.download.lock() { + *p = DownloadProgress::default(); + } + let name = state + .launcher + .as_ref() + .expect("launcher set") + .name + .clone(); + let progress = state.download.clone(); + return Task::perform( + async_blocking(move || download_blocking(&url, &name, progress)), + Message::PrepareDone, + ); } state.status = format!( @@ -583,32 +598,9 @@ fn view_install(state: &State) -> Element<'_, Message> { ] .align_y(Alignment::Start); - // ── Source / installer card (only shown in Idle) ─────────────────────────── - let source_card: Element = if matches!(state.stage, Stage::Idle) { - let inner: Element = if is_official { - column![ - text("Installer").size(12).style(|_: &Theme| text::Style { - color: Some(Color::from_rgb(0.55, 0.75, 1.0)), - }), - row![ - text("✓ Official installer").size(13).style(|_: &Theme| text::Style { - color: Some(Color::from_rgb(0.35, 0.85, 0.45)), - }), - iced::widget::horizontal_space(), - ] - .align_y(Alignment::Center), - text("Using the official download. To use a different installer, paste a URL or path below.") - .size(11) - .style(|_: &Theme| text::Style { color: Some(Color::from_rgb(0.45, 0.45, 0.45)) }), - text_input("Custom URL or local .exe path (optional)", &state.source) - .on_input(Message::SourceChanged) - .padding(7) - .size(12), - ] - .spacing(6) - .into() - } else { - column![ + // ── Source / installer card (only shown in Idle, for custom URLs) ──────── + let source_card: Element = if matches!(state.stage, Stage::Idle) && !is_official { + let inner: Element = column![ text("Installer").size(12).style(|_: &Theme| text::Style { color: Some(Color::from_rgb(0.55, 0.75, 1.0)), }), @@ -617,8 +609,7 @@ fn view_install(state: &State) -> Element<'_, Message> { .padding(8), ] .spacing(6) - .into() - }; + .into(); section_card(inner) } else { text("").into()