feat: Change to local user ini (not native)
Windows registry is horrible to deal with and makes it impractical to pass settings to the Core when run via daemon on Windows. - Pass settings path to Core when launched via daemon - Introduce portable mode detection logic on Windows - Generalize `m_settingsFile` use - Reduce #ifdef size for Settings ctor path logic
This commit is contained in:
committed by
Chris Rizzitello
parent
3ece50e292
commit
bb1394ceeb
@ -20,45 +20,42 @@ Settings *Settings::instance()
|
||||
|
||||
void Settings::setSettingFile(const QString &settingsFile)
|
||||
{
|
||||
if (instance()->m_portableSettingsFile == settingsFile) {
|
||||
qDebug().noquote() << "settings file already in use";
|
||||
if (instance()->settingsFile() == settingsFile) {
|
||||
qDebug("settings file already set, skipping");
|
||||
return;
|
||||
}
|
||||
|
||||
instance()->m_portableSettingsFile = settingsFile;
|
||||
if (instance()->m_settings)
|
||||
instance()->m_settings->deleteLater();
|
||||
instance()->m_settings = new QSettings(instance()->m_portableSettingsFile, QSettings::IniFormat);
|
||||
instance()->m_settingsProxy->load(instance()->m_portableSettingsFile);
|
||||
qInfo().noquote() << "settings file:" << instance()->m_settings->fileName();
|
||||
|
||||
instance()->m_settings = new QSettings(settingsFile, QSettings::IniFormat);
|
||||
instance()->m_settingsProxy->load(settingsFile);
|
||||
qInfo().noquote() << "settings file changed:" << instance()->m_settings->fileName();
|
||||
}
|
||||
|
||||
Settings::Settings(QObject *parent) : QObject(parent)
|
||||
{
|
||||
QString fileToLoad;
|
||||
#ifdef Q_OS_WIN
|
||||
m_portableSettingsFile = m_portableSettingsFile.arg(QCoreApplication::applicationDirPath(), kAppName);
|
||||
if (QFile(m_portableSettingsFile).exists()) {
|
||||
fileToLoad = m_portableSettingsFile;
|
||||
m_settings = new QSettings(fileToLoad, QSettings::IniFormat);
|
||||
} else {
|
||||
m_settings = new QSettings(QSettings::NativeFormat, QSettings::UserScope, kAppName, kAppName);
|
||||
}
|
||||
const auto portableFile = portableSettingsFile();
|
||||
qDebug().noquote() << "checking for portable settings file at:" << portableFile;
|
||||
if (QFile(portableFile).exists())
|
||||
fileToLoad = portableFile;
|
||||
#else
|
||||
if (!qEnvironmentVariable("XDG_CONFIG_HOME").isEmpty())
|
||||
fileToLoad = QStringLiteral("%1/%2/%2.conf").arg(qEnvironmentVariable("XDG_CONFIG_HOME"), kAppName);
|
||||
#endif
|
||||
else if (QFile(UserSettingFile).exists())
|
||||
fileToLoad = UserSettingFile;
|
||||
else if (QFile(SystemSettingFile).exists())
|
||||
fileToLoad = SystemSettingFile;
|
||||
else
|
||||
fileToLoad = UserSettingFile;
|
||||
m_settings = new QSettings(fileToLoad, QSettings::IniFormat);
|
||||
#endif
|
||||
|
||||
m_settings = new QSettings(fileToLoad, QSettings::IniFormat);
|
||||
m_settingsProxy = std::make_shared<QSettingsProxy>();
|
||||
m_settingsProxy->load(fileToLoad);
|
||||
qInfo().noquote() << "settings file:" << m_settings->fileName();
|
||||
qInfo().noquote() << "initial settings file:" << m_settings->fileName();
|
||||
}
|
||||
|
||||
void Settings::cleanSettings()
|
||||
@ -143,7 +140,7 @@ QVariant Settings::defaultValue(const QString &key)
|
||||
return 4; // INFO
|
||||
|
||||
if (key == Daemon::Elevate)
|
||||
return Settings::isNativeMode();
|
||||
return !Settings::isPortableMode();
|
||||
|
||||
if (key == Core::UpdateUrl)
|
||||
return kUrlUpdateCheck;
|
||||
@ -155,10 +152,12 @@ QVariant Settings::defaultValue(const QString &key)
|
||||
return 24800;
|
||||
|
||||
if (key == Core::ProcessMode) {
|
||||
if (Settings::isNativeMode())
|
||||
#ifdef Q_OS_WIN
|
||||
if (!Settings::isPortableMode())
|
||||
return Settings::ProcessMode::Service;
|
||||
else
|
||||
return Settings::ProcessMode::Desktop;
|
||||
#endif
|
||||
|
||||
return Settings::ProcessMode::Desktop;
|
||||
}
|
||||
|
||||
if (key == Daemon::LogFile) {
|
||||
@ -196,14 +195,13 @@ QStringList Settings::validKeys()
|
||||
|
||||
bool Settings::isWritable()
|
||||
{
|
||||
if (Settings::isNativeMode())
|
||||
return true;
|
||||
return instance()->m_settings->isWritable();
|
||||
}
|
||||
|
||||
bool Settings::isNativeMode()
|
||||
bool Settings::isPortableMode()
|
||||
{
|
||||
return instance()->m_settings->format() == QSettings::NativeFormat;
|
||||
// Enable portable mode only if the portable settings file exists in the expected location.
|
||||
return QFile(portableSettingsFile()).exists();
|
||||
}
|
||||
|
||||
QString Settings::settingsFile()
|
||||
@ -213,8 +211,11 @@ QString Settings::settingsFile()
|
||||
|
||||
QString Settings::settingsPath()
|
||||
{
|
||||
if (instance()->isNativeMode())
|
||||
#ifdef Q_OS_WIN
|
||||
if (!isPortableMode())
|
||||
return SystemDir;
|
||||
#endif
|
||||
|
||||
return QFileInfo(instance()->m_settings->fileName()).absolutePath();
|
||||
}
|
||||
|
||||
@ -263,3 +264,10 @@ void Settings::restoreDefaultSettings()
|
||||
instance()->setValue(key, defaultValue(key));
|
||||
}
|
||||
}
|
||||
|
||||
QString Settings::portableSettingsFile()
|
||||
{
|
||||
static const auto filename =
|
||||
QStringLiteral("%1/settings/%2.conf").arg(QCoreApplication::applicationDirPath(), kAppName);
|
||||
return filename;
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ class Settings : public QObject
|
||||
Q_OBJECT
|
||||
public:
|
||||
#if defined(Q_OS_WIN)
|
||||
inline const static auto UserDir = QStringLiteral("%1/AppData/Local/%2").arg(QDir::homePath(), kAppName);
|
||||
inline const static auto UserDir = QStringLiteral("%1/AppData/Roaming/%2").arg(QDir::homePath(), kAppName);
|
||||
inline const static auto SystemDir = QStringLiteral("%1ProgramData/%2").arg(QDir::rootPath(), kAppName);
|
||||
#elif defined(Q_OS_MAC)
|
||||
inline const static auto UserDir = QStringLiteral("%1/Library/%2").arg(QDir::homePath(), kAppName);
|
||||
@ -28,6 +28,7 @@ public:
|
||||
inline const static auto UserDir = QStringLiteral("%1/.config/%2").arg(QDir::homePath(), kAppName);
|
||||
inline const static auto SystemDir = QStringLiteral("/etc/%1").arg(kAppName);
|
||||
#endif
|
||||
|
||||
inline const static auto UserSettingFile = QStringLiteral("%1/%2.conf").arg(UserDir, kAppName);
|
||||
inline const static auto SystemSettingFile = QStringLiteral("%1/%2.conf").arg(SystemDir, kAppName);
|
||||
|
||||
@ -120,7 +121,7 @@ public:
|
||||
static void restoreDefaultSettings();
|
||||
static QVariant defaultValue(const QString &key);
|
||||
static bool isWritable();
|
||||
static bool isNativeMode();
|
||||
static bool isPortableMode();
|
||||
static QString settingsFile();
|
||||
static QString settingsPath();
|
||||
static QString tlsDir();
|
||||
@ -132,6 +133,7 @@ public:
|
||||
static void save(bool emitSaving = true);
|
||||
static QStringList validKeys();
|
||||
static int logLevelToInt(const QString &level = "INFO");
|
||||
static QString portableSettingsFile();
|
||||
|
||||
Q_SIGNALS:
|
||||
void settingsChanged(const QString key);
|
||||
@ -145,7 +147,6 @@ private:
|
||||
void cleanSettings();
|
||||
|
||||
QSettings *m_settings = nullptr;
|
||||
QString m_portableSettingsFile = QStringLiteral("%1/settings/%2.conf");
|
||||
std::shared_ptr<QSettingsProxy> m_settingsProxy;
|
||||
|
||||
// clang-format off
|
||||
|
||||
@ -44,7 +44,7 @@ void clearSettings(bool enableRestart)
|
||||
profileDir.removeRecursively();
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
if (!Settings::isNativeMode()) {
|
||||
if (Settings::isPortableMode()) {
|
||||
// make a new empty portable settings file
|
||||
if (profileDir.mkpath(Settings::settingsPath())) {
|
||||
QFile file(Settings::settingsFile());
|
||||
|
||||
@ -349,6 +349,7 @@ void CoreProcess::start(std::optional<ProcessMode> processModeOption)
|
||||
if (processMode == ProcessMode::Desktop) {
|
||||
startForegroundProcess(args);
|
||||
} else if (processMode == ProcessMode::Service) {
|
||||
args.append({QStringLiteral("--settings"), Settings::settingsFile()});
|
||||
startProcessFromDaemon(args);
|
||||
}
|
||||
|
||||
|
||||
@ -271,8 +271,9 @@ void SettingsDialog::updateControls()
|
||||
ui->comboTlsKeyLength->setEnabled(writable);
|
||||
ui->cbCloseToTray->setEnabled(writable);
|
||||
|
||||
// Handle enable and disable of service items
|
||||
if (Settings::isNativeMode()) {
|
||||
// Portable mode only ever applies to Windows.
|
||||
// Daemon options should only be available on Windows when *not* in portable mode.
|
||||
if (!Settings::isPortableMode()) {
|
||||
ui->groupService->setEnabled(writable);
|
||||
ui->cbElevateDaemon->setEnabled(writable && serviceChecked);
|
||||
} else if (ui->groupService->isVisibleTo(ui->tabAdvanced)) {
|
||||
|
||||
@ -16,7 +16,7 @@ void SettingsTests::initTestCase()
|
||||
oldSettings.remove();
|
||||
}
|
||||
|
||||
void SettingsTests::setSettingsFile()
|
||||
void SettingsTests::setSettingFile()
|
||||
{
|
||||
Settings::setSettingFile(m_settingsFile);
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ class SettingsTests : public QObject
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
// Test are run in order top to bottom
|
||||
void setSettingsFile();
|
||||
void setSettingFile();
|
||||
void settingsFile();
|
||||
void settingsPath();
|
||||
void tlsDir();
|
||||
@ -24,9 +24,18 @@ private Q_SLOTS:
|
||||
void checkValidSettings();
|
||||
|
||||
private:
|
||||
inline static const QString m_settingsPath = QStringLiteral("tmp/test");
|
||||
inline static const QString m_settingsFile = QStringLiteral("%1/Deskflow.conf").arg(m_settingsPath);
|
||||
inline static const QString m_expectedTlsDir = QStringLiteral("tmp/test/%1").arg(kTlsDirName);
|
||||
inline static const QString m_settingsPathTemp = QStringLiteral("tmp/test");
|
||||
inline static const QString m_settingsFile = QStringLiteral("%1/Deskflow.conf").arg(m_settingsPathTemp);
|
||||
|
||||
// Gotcha: On Windows non-portable mode, additional config files such as TLS config are saved
|
||||
// in 'Program Data' and are not stored in the same place as the settings file.
|
||||
#ifdef Q_OS_WIN
|
||||
inline static const QString m_settingsPath = Settings::SystemDir;
|
||||
#else
|
||||
inline static const QString m_settingsPath = m_settingsPathTemp;
|
||||
#endif
|
||||
|
||||
inline static const QString m_expectedTlsDir = QStringLiteral("%1/%2").arg(m_settingsPath, kTlsDirName);
|
||||
inline static const QString m_expectedTlsLocalDB =
|
||||
QStringLiteral("%1/%2").arg(m_expectedTlsDir, kTlsFingerprintLocalFilename);
|
||||
inline static const QString m_expectedTlsServerDB =
|
||||
|
||||
Reference in New Issue
Block a user