gui: transition to tray on close, auto-download official installers in setup
This commit is contained in:
+7
-7
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
pkgname=umutray
|
pkgname=umutray
|
||||||
pkgver=0.1.0
|
pkgver=0.1.0
|
||||||
pkgrel=2
|
pkgrel=4
|
||||||
pkgdesc='Tray-based Wine launcher manager for Linux via umu/Proton-GE'
|
pkgdesc='Tray-based Wine launcher manager for Linux via umu/Proton-GE'
|
||||||
arch=('x86_64')
|
arch=('x86_64')
|
||||||
url='https://git.aleshym.co/funman300/umutray'
|
url='https://git.aleshym.co/funman300/umutray'
|
||||||
@@ -48,13 +48,13 @@ build() {
|
|||||||
package() {
|
package() {
|
||||||
cd "$pkgname"
|
cd "$pkgname"
|
||||||
|
|
||||||
# Binary
|
# Binary — install to ~/.local/bin for user-local usage
|
||||||
install -Dm755 target/release/umutray "$pkgdir/usr/bin/umutray"
|
install -Dm755 target/release/umutray "${HOME}/.local/bin/umutray"
|
||||||
|
|
||||||
# App menu entry (.desktop uses /usr/bin/umutray as the exec path)
|
# App menu entry for the current user
|
||||||
install -Dm644 umutray.desktop "$pkgdir/usr/share/applications/umutray.desktop"
|
install -Dm644 umutray.desktop "${HOME}/.local/share/applications/umutray.desktop"
|
||||||
sed -i "s|Exec=umutray|Exec=/usr/bin/umutray|" \
|
sed -i "s|Exec=umutray|Exec=${HOME}/.local/bin/umutray|" \
|
||||||
"$pkgdir/usr/share/applications/umutray.desktop"
|
"${HOME}/.local/share/applications/umutray.desktop"
|
||||||
|
|
||||||
# License
|
# License
|
||||||
install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
|
install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
|
||||||
|
|||||||
+6
-1
@@ -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 } => {
|
Commands::Detect { dir, apply } => {
|
||||||
detect::run(&config, &dir, apply)?;
|
detect::run(&config, &dir, apply)?;
|
||||||
|
|||||||
+27
-36
@@ -171,16 +171,31 @@ fn update(state: &mut State, message: Message) -> Task<Message> {
|
|||||||
preset.prefix_dir = PathBuf::from(&prefix);
|
preset.prefix_dir = PathBuf::from(&prefix);
|
||||||
|
|
||||||
// If we know the official installer URL, pre-fill source and
|
// 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() {
|
if let Some(url) = preset.installer_url.clone() {
|
||||||
state.source = url;
|
state.source = url.clone();
|
||||||
state.stage = Stage::Idle;
|
|
||||||
state.status = format!(
|
|
||||||
"Ready to download the official {} installer. Press Download → to begin.",
|
|
||||||
preset.display
|
|
||||||
);
|
|
||||||
state.launcher = Some(preset);
|
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!(
|
state.status = format!(
|
||||||
@@ -583,32 +598,9 @@ fn view_install(state: &State) -> Element<'_, Message> {
|
|||||||
]
|
]
|
||||||
.align_y(Alignment::Start);
|
.align_y(Alignment::Start);
|
||||||
|
|
||||||
// ── Source / installer card (only shown in Idle) ───────────────────────────
|
// ── Source / installer card (only shown in Idle, for custom URLs) ────────
|
||||||
let source_card: Element<Message> = if matches!(state.stage, Stage::Idle) {
|
let source_card: Element<Message> = if matches!(state.stage, Stage::Idle) && !is_official {
|
||||||
let inner: Element<Message> = if is_official {
|
let inner: Element<Message> = column![
|
||||||
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![
|
|
||||||
text("Installer").size(12).style(|_: &Theme| text::Style {
|
text("Installer").size(12).style(|_: &Theme| text::Style {
|
||||||
color: Some(Color::from_rgb(0.55, 0.75, 1.0)),
|
color: Some(Color::from_rgb(0.55, 0.75, 1.0)),
|
||||||
}),
|
}),
|
||||||
@@ -617,8 +609,7 @@ fn view_install(state: &State) -> Element<'_, Message> {
|
|||||||
.padding(8),
|
.padding(8),
|
||||||
]
|
]
|
||||||
.spacing(6)
|
.spacing(6)
|
||||||
.into()
|
.into();
|
||||||
};
|
|
||||||
section_card(inner)
|
section_card(inner)
|
||||||
} else {
|
} else {
|
||||||
text("").into()
|
text("").into()
|
||||||
|
|||||||
Reference in New Issue
Block a user