Skip to content

Commit 0b99db6

Browse files
committed
Qt: Ensure settings are writable before running setup wizard
1 parent 693982d commit 0b99db6

File tree

1 file changed

+40
-17
lines changed

1 file changed

+40
-17
lines changed

src/duckstation-qt/qthost.cpp

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ static bool InitializeConfig(std::string settings_filename);
8989
static bool ShouldUsePortableMode();
9090
static void SetAppRoot();
9191
static void SetResourcesDirectory();
92-
static void SetDataDirectory();
92+
static bool SetDataDirectory();
9393
static bool SetCriticalFolders();
9494
static void SetDefaultSettings(SettingsInterface& si, bool system, bool controller);
9595
static void SaveSettings();
@@ -335,13 +335,13 @@ bool QtHost::InitializeConfig(std::string settings_filename)
335335
if (settings_filename.empty())
336336
settings_filename = Path::Combine(EmuFolders::DataRoot, "settings.ini");
337337

338-
Log_InfoPrintf("Loading config from %s.", settings_filename.c_str());
339-
s_run_setup_wizard = s_run_setup_wizard || !FileSystem::FileExists(settings_filename.c_str());
338+
const bool settings_exists = FileSystem::FileExists(settings_filename.c_str());
339+
Log_InfoFmt("Loading config from {}.", settings_filename);
340340
s_base_settings_interface = std::make_unique<INISettingsInterface>(std::move(settings_filename));
341341
Host::Internal::SetBaseSettingsLayer(s_base_settings_interface.get());
342342

343343
uint settings_version;
344-
if (!s_base_settings_interface->Load() ||
344+
if (!settings_exists || !s_base_settings_interface->Load() ||
345345
!s_base_settings_interface->GetUIntValue("Main", "SettingsVersion", &settings_version) ||
346346
settings_version != SETTINGS_VERSION)
347347
{
@@ -356,9 +356,22 @@ bool QtHost::InitializeConfig(std::string settings_filename)
356356
s_base_settings_interface->SetBoolValue("ControllerPorts", "ControllerSettingsMigrated", true);
357357
SetDefaultSettings(*s_base_settings_interface, true, true);
358358

359-
// Don't save if we're running the setup wizard. We want to run it next time if they don't finish it.
360-
if (!s_run_setup_wizard)
361-
s_base_settings_interface->Save();
359+
// Flag for running the setup wizard if this is our first run. We want to run it next time if they don't finish it.
360+
s_base_settings_interface->SetBoolValue("Main", "SetupWizardIncomplete", true);
361+
362+
// Make sure we can actually save the config, and the user doesn't have some permission issue.
363+
Error error;
364+
if (!s_base_settings_interface->Save(&error))
365+
{
366+
QMessageBox::critical(
367+
nullptr, QStringLiteral("DuckStation"),
368+
QStringLiteral(
369+
"Failed to save configuration to\n\n%1\n\nThe error was: %2\n\nPlease ensure this directory is writable. You "
370+
"can also try portable mode by creating portable.txt in the same directory you installed DuckStation into.")
371+
.arg(QString::fromStdString(s_base_settings_interface->GetFileName()))
372+
.arg(QString::fromStdString(error.GetDescription())));
373+
return false;
374+
}
362375
}
363376

364377
// Setup wizard was incomplete last time?
@@ -391,7 +404,8 @@ bool QtHost::SetCriticalFolders()
391404
{
392405
SetAppRoot();
393406
SetResourcesDirectory();
394-
SetDataDirectory();
407+
if (!SetDataDirectory())
408+
return false;
395409

396410
// logging of directories in case something goes wrong super early
397411
Log_DevPrintf("AppRoot Directory: %s", EmuFolders::AppRoot.c_str());
@@ -438,16 +452,16 @@ void QtHost::SetResourcesDirectory()
438452
#endif
439453
}
440454

441-
void QtHost::SetDataDirectory()
455+
bool QtHost::SetDataDirectory()
442456
{
443457
// Already set, e.g. by -portable.
444458
if (!EmuFolders::DataRoot.empty())
445-
return;
459+
return true;
446460

447461
if (ShouldUsePortableMode())
448462
{
449463
EmuFolders::DataRoot = EmuFolders::AppRoot;
450-
return;
464+
return true;
451465
}
452466

453467
#if defined(_WIN32)
@@ -491,13 +505,26 @@ void QtHost::SetDataDirectory()
491505
if (!EmuFolders::DataRoot.empty() && !FileSystem::DirectoryExists(EmuFolders::DataRoot.c_str()))
492506
{
493507
// we're in trouble if we fail to create this directory... but try to hobble on with portable
494-
if (!FileSystem::EnsureDirectoryExists(EmuFolders::DataRoot.c_str(), false))
495-
EmuFolders::DataRoot.clear();
508+
Error error;
509+
if (!FileSystem::EnsureDirectoryExists(EmuFolders::DataRoot.c_str(), false, &error))
510+
{
511+
// no point translating, config isn't loaded
512+
QMessageBox::critical(
513+
nullptr, QStringLiteral("DuckStation"),
514+
QStringLiteral("Failed to create data directory at path\n\n%1\n\nThe error was: %2\nPlease ensure this "
515+
"directory is writable. You can also try portable mode by creating portable.txt in the same "
516+
"directory you installed DuckStation into.")
517+
.arg(QString::fromStdString(EmuFolders::DataRoot))
518+
.arg(QString::fromStdString(error.GetDescription())));
519+
return false;
520+
}
496521
}
497522

498523
// couldn't determine the data directory? fallback to portable.
499524
if (EmuFolders::DataRoot.empty())
500525
EmuFolders::DataRoot = EmuFolders::AppRoot;
526+
527+
return true;
501528
}
502529

503530
void Host::LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock)
@@ -2212,10 +2239,6 @@ bool QtHost::ParseCommandLineParametersAndInitializeConfig(QApplication& app,
22122239

22132240
bool QtHost::RunSetupWizard()
22142241
{
2215-
// Set a flag in the config so that even though we created the ini, we'll run the wizard next time.
2216-
Host::SetBaseBoolSettingValue("Main", "SetupWizardIncomplete", true);
2217-
Host::CommitBaseSettingChanges();
2218-
22192242
SetupWizardDialog dialog;
22202243
if (dialog.exec() == QDialog::Rejected)
22212244
return false;

0 commit comments

Comments
 (0)