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>
This commit is contained in:
funman300
2026-04-18 19:43:55 -07:00
parent 05a12b7cee
commit 74f21b6b75
+37 -5
View File
@@ -27,6 +27,9 @@ pub enum Message {
InstallPressed,
InstallDone(Result<i32, String>),
Tick,
// Finished stage
LaunchNow,
Close,
}
#[derive(Debug, Clone)]
@@ -282,7 +285,6 @@ fn update(state: &mut State, message: Message) -> Task<Message> {
)
}
Message::InstallDone(res) => {
state.stage = Stage::Finished;
let launcher = state
.launcher
.as_ref()
@@ -294,6 +296,9 @@ fn update(state: &mut State, message: Message) -> Task<Message> {
state.config.launchers.push(launcher.clone());
let _ = state.config.save();
}
state.stage = Stage::Finished;
} else {
state.stage = Stage::Finished;
}
// Always clean up downloaded temp file
if let Some(tmp) = state.downloaded_temp.take() {
@@ -301,10 +306,8 @@ fn update(state: &mut State, message: Message) -> Task<Message> {
}
state.status = match res {
Ok(code) if exe.exists() => format!(
"✓ Installer finished (umu exit {code}); {} is present.\n\
You can now run: umutray launch {}",
exe.display(),
launcher.name,
"✓ Installer finished (exit {code}). {} is ready.",
launcher.display,
),
Ok(code) => format!(
"umu-run exited {code} but the expected exe is not at {}.\n\
@@ -315,6 +318,17 @@ fn update(state: &mut State, message: Message) -> Task<Message> {
};
Task::none()
}
Message::LaunchNow => {
if let Some(launcher) = &state.launcher {
let config = state.config.clone();
let launcher = launcher.clone();
std::thread::spawn(move || {
let _ = crate::launcher::launch(&config, &launcher);
});
}
iced::exit()
}
Message::Close => iced::exit(),
}
}
@@ -427,6 +441,11 @@ fn view_install(state: &State) -> Element<'_, Message> {
let prepare_enabled = matches!(state.stage, Stage::Idle | Stage::Ready | Stage::Finished);
let install_enabled = matches!(state.stage, Stage::Ready);
let finished = matches!(state.stage, Stage::Finished);
let install_success = finished
&& launcher
.full_exe_path()
.exists();
let prepare_btn = button(text("Download / Prepare"))
.on_press_maybe(prepare_enabled.then_some(Message::PreparePressed));
@@ -473,6 +492,18 @@ fn view_install(state: &State) -> Element<'_, Message> {
text("").into()
};
let finished_row: Element<Message> = if finished {
let close_btn = button(text("Close").size(13))
.on_press(Message::Close)
.style(button::secondary);
let launch_btn = button(text("Launch now").size(13))
.on_press_maybe(install_success.then_some(Message::LaunchNow))
.style(button::primary);
row![close_btn, launch_btn].spacing(10).into()
} else {
text("").into()
};
let body = column![
header,
prefix,
@@ -482,6 +513,7 @@ fn view_install(state: &State) -> Element<'_, Message> {
row![prepare_btn, install_btn].spacing(12),
progress_row,
status,
finished_row,
log_pane,
]
.spacing(12)