From e9cd9453ea86b4b60472b87a481808443fed17a8 Mon Sep 17 00:00:00 2001 From: BruebachL <44814898+BruebachL@users.noreply.github.com> Date: Fri, 25 Sep 2026 08:32:03 +0200 Subject: [PATCH] [Startup] Run the onboarding wizard before the first-run set dialog (#7349) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On a clean install, checkUnknownSets() fired before the onboarding wizard, so the legacy 'all the sets have been enabled' welcome and the Manage Sets dialog appeared first - with no card data there are no sets to manage yet. Defer the set check until after the wizard closes, suppress its dialogs while onboarding runs, and enable newly downloaded sets silently instead. Co-authored-by: Lukas BrĂ¼bach --- cockatrice/src/interface/window_main.cpp | 36 ++++++++++++++++++++---- cockatrice/src/interface/window_main.h | 3 +- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/cockatrice/src/interface/window_main.cpp b/cockatrice/src/interface/window_main.cpp index 595d38d5b..ae967312d 100644 --- a/cockatrice/src/interface/window_main.cpp +++ b/cockatrice/src/interface/window_main.cpp @@ -575,11 +575,18 @@ MainWindow::MainWindow(QWidget *parent) void MainWindow::startupConfigCheck() { + const bool isCleanInstall = SettingsCache::instance().network().getClientVersion() == CLIENT_INFO_NOT_SET; + // checkUnknownSets() is intentionally deferred from the card database load // (which runs in main() before MainWindow exists) so that // cardDatabaseNewSetsFound / cardDatabaseAllNewSetsEnabled have live // receivers when emitted. - CardDatabaseManager::getInstance()->checkUnknownSets(); + // On a clean install the onboarding wizard owns the first-run experience; + // wait until it closes so the legacy "all sets enabled" welcome and the + // Manage Sets dialog don't appear first. + if (!isCleanInstall) { + CardDatabaseManager::getInstance()->checkUnknownSets(); + } if (SettingsCache::instance().debug().getLocalGameOnStartup()) { LocalGameOptions options; @@ -593,14 +600,14 @@ void MainWindow::startupConfigCheck() actCheckCommanderBracketDefinitionUpdates(); - if (SettingsCache::instance().network().getClientVersion() == CLIENT_INFO_NOT_SET) { + if (isCleanInstall) { // no config found, 99% new clean install qCInfo(WindowMainStartupVersionLog) << "Startup: old client version empty, assuming first start after clean install"; SettingsCache::instance().downloads().resetToDefaultURLs(); // populate the download urls SettingsCache::instance().network().setClientVersion(VERSION_STRING); actCheckServerUpdates(); - runFirstRunWizard(); + runFirstRunWizard(true); if (QString(VERSION_STRING).contains("custom", Qt::CaseInsensitive)) { SettingsCache::instance().updates().setCheckUpdatesOnStartup(false); @@ -680,7 +687,7 @@ void MainWindow::startupConfigCheck() } } -void MainWindow::runFirstRunWizard() +void MainWindow::runFirstRunWizard(bool firstRun) { auto *wizard = new FirstRunWizard(this); wizard->setAttribute(Qt::WA_DeleteOnClose); @@ -692,6 +699,19 @@ void MainWindow::runFirstRunWizard() connect(wizard, &FirstRunWizard::registerRequested, connectionController, &ConnectionController::registerToServer); connect(wizard, &FirstRunWizard::connectRequested, connectionController, &ConnectionController::connectToServer); + if (firstRun) { + // The onboarding wizard owns set handling for a clean install. Suppress + // the legacy set dialogs while it's open and run checkUnknownSets() once + // it closes so the sets end up enabled in the right order. + firstRunWizardActive = true; + connect(wizard, &QDialog::finished, this, [this] { + QTimer::singleShot(0, this, [this] { + CardDatabaseManager::getInstance()->checkUnknownSets(); + firstRunWizardActive = false; + }); + }); + } + wizard->setModal(true); wizard->show(); } @@ -995,7 +1015,7 @@ void MainWindow::cardDatabaseLoadingFailed() void MainWindow::cardDatabaseNewSetsFound(int numUnknownSets, QStringList unknownSetsNames) { - if (SettingsCache::instance().updates().getAlwaysEnableNewSets()) { + if (firstRunWizardActive || SettingsCache::instance().updates().getAlwaysEnableNewSets()) { CardDatabaseManager::getInstance()->enableAllUnknownSets(); const auto reloadOk1 = QtConcurrent::run([] { CardDatabaseManager::getInstance()->reloadCardDatabasesAndNotify(); }); @@ -1038,6 +1058,12 @@ void MainWindow::cardDatabaseNewSetsFound(int numUnknownSets, QStringList unknow void MainWindow::cardDatabaseAllNewSetsEnabled() { + if (firstRunWizardActive || CardDatabaseManager::getInstance()->getCardList().isEmpty()) { + // The onboarding wizard owns the first-run messaging on a clean install, + // and with no card data there are no sets to have enabled. + return; + } + QMessageBox::information( this, tr("Welcome"), tr("Hi! It seems like you're running this version of Cockatrice for the first time.\nAll the sets in the card " diff --git a/cockatrice/src/interface/window_main.h b/cockatrice/src/interface/window_main.h index 9e45a4c3e..fc7980d16 100644 --- a/cockatrice/src/interface/window_main.h +++ b/cockatrice/src/interface/window_main.h @@ -139,7 +139,7 @@ private: void createTrayIcon(); int getNextCustomSetPrefix(QDir dataDir); - void runFirstRunWizard(); + void runFirstRunWizard(bool firstRun = false); inline QString getCardUpdaterBinaryName() { @@ -169,6 +169,7 @@ private: bool bHasActivated, askedForDbUpdater; bool skipStartupAutoConnect = false; bool startupAutoConnectAttempted = false; + bool firstRunWizardActive = false; QProcess *cardUpdateProcess; QByteArray cardUpdateOutputBuffer; DlgViewLog *logviewDialog;