Skip to content

Commit 5f4e15b

Browse files
fix(launcher): fix GUI freeze during PKG install (async process wait)
1 parent ad6301f commit 5f4e15b

1 file changed

Lines changed: 34 additions & 29 deletions

File tree

src/launcher/src/mainDialog.cpp

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -542,38 +542,43 @@ void MainDialogPrivate::RunInstall(const QString& file, const QString& flag) {
542542
}
543543
#endif
544544

545-
// After launching the install process, wait for it to finish, then move
546-
// the extracted files to the games directory and rescan the library.
547-
// This makes installed PKGs appear in the main game window.
545+
// After launching the install process, move the extracted files to the
546+
// games directory and rescan the library, using an async signal so we
547+
// dont block the GUI thread (which was causing the launcher to freeze).
548548
if (flag == QStringLiteral("--install-pkg")) {
549-
if (process->waitForFinished(60000)) { // wait up to 60s for extraction
550-
QString pkg_out_dir = QDir(dir.path()).filePath(QStringLiteral("pkg_out/pfs_files"));
551-
QStringList game_dirs = m_ui->widget->GetGameDirectories();
552-
if (!game_dirs.isEmpty() && QDir(pkg_out_dir).exists()) {
553-
QString games_dir = game_dirs.first();
554-
if (!games_dir.isEmpty() && QDir(games_dir).exists()) {
555-
QString content_id = QFileInfo(file).completeBaseName();
556-
QString dest_dir = QDir(games_dir).filePath(content_id);
557-
QDir().mkpath(dest_dir);
558-
559-
QDir source(pkg_out_dir);
560-
QStringList files = source.entryList(QDir::Files | QDir::NoDotAndDotDot);
561-
int moved = 0;
562-
for (const auto& fname : files) {
563-
QString src = source.filePath(fname);
564-
QString dst = QDir(dest_dir).filePath(fname);
565-
if (QFile::exists(dst)) QFile::remove(dst);
566-
if (QFile::rename(src, dst)) moved++;
549+
QString pkg_out_dir = QDir(dir.path()).filePath(QStringLiteral("pkg_out/pfs_files"));
550+
QStringList game_dirs = m_ui->widget->GetGameDirectories();
551+
QString content_id = QFileInfo(file).completeBaseName();
552+
553+
QObject::connect(process, &QProcess::finished, m_main_dialog,
554+
[this, process, pkg_out_dir, game_dirs, content_id](int exitCode, QProcess::ExitStatus) {
555+
if (!game_dirs.isEmpty() && QDir(pkg_out_dir).exists()) {
556+
QString games_dir = game_dirs.first();
557+
if (!games_dir.isEmpty() && QDir(games_dir).exists()) {
558+
QString dest_dir = QDir(games_dir).filePath(content_id);
559+
QDir().mkpath(dest_dir);
560+
561+
QDir source(pkg_out_dir);
562+
QStringList files = source.entryList(QDir::Files | QDir::NoDotAndDotDot);
563+
int moved = 0;
564+
for (const auto& fname : files) {
565+
QString src = source.filePath(fname);
566+
QString dst = QDir(dest_dir).filePath(fname);
567+
if (QFile::exists(dst)) QFile::remove(dst);
568+
if (QFile::rename(src, dst)) moved++;
569+
}
570+
571+
m_ui->widget->ScanGameDirectory();
572+
573+
QMessageBox::information(m_main_dialog, tr("Install complete"),
574+
tr("Extracted %1 file(s) to:\n%2\n\nThe game should now appear in the list.").arg(moved).arg(dest_dir));
567575
}
568-
569-
// Trigger a rescan so the new game appears in the list
570-
m_ui->widget->ScanGameDirectory();
571-
572-
QMessageBox::information(m_main_dialog, tr("Install complete"),
573-
tr("Extracted %1 file(s) to:\n%2\n\nThe game should now appear in the list.").arg(moved).arg(dest_dir));
574576
}
575-
}
576-
}
577+
process->deleteLater();
578+
});
579+
} else {
580+
// For non-pkg installs, auto-cleanup the process
581+
QObject::connect(process, &QProcess::finished, process, &QProcess::deleteLater);
577582
}
578583
}
579584

0 commit comments

Comments
 (0)