feat: save geometry into into a state file

fixes: #9132
This commit is contained in:
sithlord48
2025-11-11 14:44:28 -05:00
committed by Chris Rizzitello
parent ddcd2f0ff1
commit aca08a5e74
10 changed files with 65 additions and 5 deletions

View File

@ -12,6 +12,7 @@
#include <QFile>
#include <QRect>
#include <QRegularExpression>
#include <QStandardPaths>
Settings *Settings::instance()
{
@ -34,6 +35,20 @@ void Settings::setSettingsFile(const QString &settingsFile)
qInfo().noquote() << "settings file changed:" << instance()->m_settings->fileName();
}
void Settings::setStateFile(const QString &stateFile)
{
if (instance()->m_stateSettings->fileName() == stateFile) {
qDebug("settings file already set, skipping");
return;
}
if (instance()->m_stateSettings)
instance()->m_stateSettings->deleteLater();
instance()->m_stateSettings = new QSettings(stateFile, QSettings::IniFormat);
qInfo().noquote() << "settings file changed:" << instance()->m_stateSettings->fileName();
}
Settings::Settings(QObject *parent) : QObject(parent)
{
QString fileToLoad;
@ -57,6 +72,13 @@ Settings::Settings(QObject *parent) : QObject(parent)
m_settingsProxy = std::make_shared<QSettingsProxy>();
m_settingsProxy->load(fileToLoad);
qInfo().noquote() << "initial settings file:" << m_settings->fileName();
const auto stateBase = !qEnvironmentVariable("XDG_STATE_HOME").isEmpty()
? qEnvironmentVariable("XDG_STATE_HOME")
: QStandardPaths::standardLocations(QStandardPaths::GenericStateLocation).at(0);
const auto stateFile = QStringLiteral("%1/%2.state").arg(stateBase, kAppName);
m_stateSettings = new QSettings(stateFile, QSettings::IniFormat);
}
void Settings::cleanSettings()
@ -70,6 +92,17 @@ void Settings::cleanSettings()
}
}
void Settings::cleanStateSettings()
{
const QStringList keys = m_stateKeys;
for (const QString &key : keys) {
if (!m_stateKeys.contains(key))
m_stateSettings->remove(key);
if (m_stateSettings->value(key).toString().isEmpty() && !m_stateSettings->value(key).isValid())
m_stateSettings->remove(key);
}
}
int Settings::logLevelToInt(const QString &level)
{
// Can do this better later ?
@ -188,6 +221,7 @@ void Settings::save(bool emitSaving)
if (emitSaving)
Q_EMIT instance()->serverSettingsChanged();
instance()->m_settings->sync();
instance()->m_stateSettings->sync();
}
QStringList Settings::validKeys()
@ -243,21 +277,26 @@ QString Settings::tlsTrustedClientsDb()
void Settings::setValue(const QString &key, const QVariant &value)
{
if (instance()->m_settings->value(key) == value)
const bool useState = Settings::m_stateKeys.contains(key) && !instance()->isPortableMode();
auto settings = useState ? instance()->m_stateSettings : instance()->m_settings;
if (settings->value(key) == value)
return;
if (!value.isValid())
instance()->m_settings->remove(key);
settings->remove(key);
else
instance()->m_settings->setValue(key, value);
settings->setValue(key, value);
instance()->m_settings->sync();
settings->sync();
Q_EMIT instance()->settingsChanged(key);
}
QVariant Settings::value(const QString &key)
{
return instance()->m_settings->value(key, defaultValue(key));
const bool useState = Settings::m_stateKeys.contains(key) && !instance()->isPortableMode();
auto settings = useState ? instance()->m_stateSettings : instance()->m_settings;
return settings->value(key, defaultValue(key));
}
void Settings::restoreDefaultSettings()

View File

@ -117,6 +117,7 @@ public:
static Settings *instance();
static void setSettingsFile(const QString &settingsFile = QString());
static void setStateFile(const QString &stateFile = QString());
static void setValue(const QString &key = QString(), const QVariant &value = QVariant());
static QVariant value(const QString &key = QString());
static void restoreDefaultSettings();
@ -146,8 +147,10 @@ private:
Settings(const Settings &other) = delete;
~Settings() override = default;
void cleanSettings();
void cleanStateSettings();
QSettings *m_settings = nullptr;
QSettings *m_stateSettings = nullptr;
std::shared_ptr<QSettingsProxy> m_settingsProxy;
// clang-format off
@ -226,5 +229,8 @@ private:
, Settings::Security::TlsEnabled
, Settings::Security::CheckPeers
};
// Settings saved in our State file
inline static const QStringList m_stateKeys = { Settings::Gui::WindowGeometry };
// clang-format on
};

View File

@ -35,6 +35,9 @@ void clearSettings(bool enableRestart)
qDebug("clearing settings");
Settings::proxy().clear();
// Reset the windowGeometry
Settings::setValue(Settings::Gui::WindowGeometry, QVariant());
// save but do not emit saving signal which will prevent the current state of
// the app config and server configs from being applied.
Settings::save(false);

View File

@ -21,6 +21,11 @@ void SettingsTests::setSettingsFile()
Settings::setSettingsFile(m_settingsFile);
}
void SettingsTests::setStateFile()
{
Settings::setStateFile(m_stateFile);
}
void SettingsTests::settingsFile()
{
QVERIFY(Settings::settingsFile().endsWith(m_settingsFile));

View File

@ -15,6 +15,7 @@ private Q_SLOTS:
void initTestCase();
// Test are run in order top to bottom
void setSettingsFile();
void setStateFile();
void settingsFile();
void settingsPath();
void tlsDir();
@ -26,6 +27,7 @@ private Q_SLOTS:
private:
inline static const QString m_settingsPathTemp = QStringLiteral("tmp/test");
inline static const QString m_settingsFile = QStringLiteral("%1/Deskflow.conf").arg(m_settingsPathTemp);
inline static const QString m_stateFile = QStringLiteral("%1/Deskflow.state").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.

View File

@ -26,6 +26,7 @@ void LoggerTests::initTestCase()
oldSettings.remove();
Settings::setSettingsFile(m_settingsFile);
Settings::setStateFile(m_stateFile);
}
void LoggerTests::newLine()

View File

@ -18,4 +18,5 @@ private Q_SLOTS:
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_stateFile = QStringLiteral("%1/Deskflow.state").arg(m_settingsPath);
};

View File

@ -20,6 +20,7 @@ void ScreenTests::initTestCase()
oldSettings.remove();
Settings::setSettingsFile(m_settingsFile);
Settings::setStateFile(m_stateFile);
}
void ScreenTests::basicFunctionality()

View File

@ -17,4 +17,5 @@ private Q_SLOTS:
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_stateFile = QStringLiteral("%1/Deskflow.state").arg(m_settingsPath);
};

View File

@ -27,6 +27,7 @@ int main(int argc, char **argv)
std::filesystem::create_directories(testDir);
Settings::setSettingsFile("tmp/test/settings.ini");
Settings::setStateFile("tmp/test/Deskflow.state");
Settings::setValue(Settings::Server::ExternalConfig, true);
ExitTimeout exitTimeout(1, "Unit tests");