From 31c71597c59f49723530f5879b8aa469de8b715d Mon Sep 17 00:00:00 2001 From: jNullj <15849761+jNullj@users.noreply.github.com> Date: Fri, 18 Aug 2023 11:22:41 +0300 Subject: [PATCH 1/8] Change conf path XDG_CACHE_HOME to XDG_STATE_HOME Keepassxc saves application state at XDG_CACHE_HOME which can be cleared on some systems periodicly. This is not desireable as app state like window size is not consistent when openning the app. To avoid this this commit is switching the path to XDG_STATE_HOME which is more fitting based on the freedesktop basedir spec (https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html), this will allow to prevent state file deletion as well. Solves #9738 --- src/core/Config.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 25048513eb..2076db6716 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -512,7 +512,17 @@ QPair Config::defaultConfigFiles() #else // On case-sensitive Operating Systems, force use of lowercase app directories configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/keepassxc"; - localConfigPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + "/keepassxc"; + // Qt does not support XDG_STATE_HOME yet, change this once XDG_STATE_HOME is added + QString xdgStateHome; + xdgStateHome = QFile::decodeName(qgetenv("XDG_STATE_HOME")); + if (!xdgStateHome.startsWith(u'/')){ + xdgStateHome.clear(); // spec says relative paths should be ignored + } + if (xdgStateHome.isEmpty()) { + xdgStateHome = QDir::homePath() + "/.local/state"; + } + + localConfigPath = xdgStateHome + "/keepassxc"; #endif QString suffix; From 134c56dff6f7120181b6478c4891b9a153cf730c Mon Sep 17 00:00:00 2001 From: jNullj <15849761+jNullj@users.noreply.github.com> Date: Fri, 18 Aug 2023 11:34:43 +0300 Subject: [PATCH 2/8] update docs for switch to XDG_STATE_HOME --- docs/topics/DownloadInstall.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/topics/DownloadInstall.adoc b/docs/topics/DownloadInstall.adoc index f5a967ec52..21172fae43 100644 --- a/docs/topics/DownloadInstall.adoc +++ b/docs/topics/DownloadInstall.adoc @@ -59,7 +59,7 @@ image::linux_store.png[] The Snap and Flatpak options are sandboxed applications (more secure). The Native option is installed with the operating system files. Read more about the limitations of these options here: https://keepassxc.org/docs/#faq-appsnap-yubikey[KeePassXC Snap FAQ] -NOTE: KeePassXC stores a configuration file in `~/.cache` to remember window position, recent files, and other local settings. If you mount this folder to a tmpdisk you will lose settings after reboot. +NOTE: KeePassXC stores a configuration file in `~/.local/state` to remember window position, recent files, and other local settings. If you mount this folder to a tmpdisk you will lose settings after reboot. === macOS To install the KeePassXC app on macOS, double click on the downloaded DMG file and use the click and drag option as shown: From b8bcf23c7698e9611d82636434e45e7e189e2f52 Mon Sep 17 00:00:00 2001 From: jNullj <15849761+jNullj@users.noreply.github.com> Date: Fri, 18 Aug 2023 12:32:09 +0300 Subject: [PATCH 3/8] fix format --- src/core/Config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 2076db6716..8472cca137 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -515,7 +515,7 @@ QPair Config::defaultConfigFiles() // Qt does not support XDG_STATE_HOME yet, change this once XDG_STATE_HOME is added QString xdgStateHome; xdgStateHome = QFile::decodeName(qgetenv("XDG_STATE_HOME")); - if (!xdgStateHome.startsWith(u'/')){ + if (!xdgStateHome.startsWith(u'/')) { xdgStateHome.clear(); // spec says relative paths should be ignored } if (xdgStateHome.isEmpty()) { From c5ca0bb3a1c62a6a56ea895beeaa11b71fa9eca1 Mon Sep 17 00:00:00 2001 From: jNullj <15849761+jNullj@users.noreply.github.com> Date: Fri, 18 Aug 2023 13:28:00 +0300 Subject: [PATCH 4/8] Migrate old conf file to new location on linux --- src/core/Config.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 8472cca137..96dacebbac 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -472,6 +472,26 @@ void Config::init(const QString& configFileName, const QString& localConfigFileN QDir().rmdir(QFileInfo(localConfigFileName).absolutePath()); } +#if defined(Q_OS_LINUX) + // Upgrade from previous KeePassXC version which stores its config + // in ~/.cache on Linux instead of ~/.local/state. + // Move file to correct location before continuing. + QString oldLocalConfigPath; + oldLocalConfigPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + "/keepassxc"; + QString suffix; +#ifdef QT_DEBUG + suffix = "_debug"; +#endif + oldLocalConfigPath += QString("/keepassxc%1.ini").arg(suffix); + oldLocalConfigPath = QDir::toNativeSeparators(oldLocalConfigPath); + if (!localConfigFileName.isEmpty() && !QFile::exists(localConfigFileName) && QFile::exists(oldLocalConfigPath)) { + QDir().mkpath(QFileInfo(localConfigFileName).absolutePath()); + QFile::copy(oldLocalConfigPath, localConfigFileName); + QFile::remove(oldLocalConfigPath); + QDir().rmdir(QFileInfo(oldLocalConfigPath).absolutePath()); + } +#endif + m_settings.reset(new QSettings(configFileName, QSettings::IniFormat)); if (!localConfigFileName.isEmpty() && configFileName != localConfigFileName) { m_localSettings.reset(new QSettings(localConfigFileName, QSettings::IniFormat)); From 2eecf9892eed4c73376fc76415a2ff43979e5e03 Mon Sep 17 00:00:00 2001 From: jNullj <15849761+jNullj@users.noreply.github.com> Date: Fri, 25 Aug 2023 23:26:03 +0300 Subject: [PATCH 5/8] remove unnecessary condition --- src/core/Config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 96dacebbac..f78e88abbf 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -484,7 +484,7 @@ void Config::init(const QString& configFileName, const QString& localConfigFileN #endif oldLocalConfigPath += QString("/keepassxc%1.ini").arg(suffix); oldLocalConfigPath = QDir::toNativeSeparators(oldLocalConfigPath); - if (!localConfigFileName.isEmpty() && !QFile::exists(localConfigFileName) && QFile::exists(oldLocalConfigPath)) { + if (!QFile::exists(localConfigFileName) && QFile::exists(oldLocalConfigPath)) { QDir().mkpath(QFileInfo(localConfigFileName).absolutePath()); QFile::copy(oldLocalConfigPath, localConfigFileName); QFile::remove(oldLocalConfigPath); From 0cd5ce425e1e26854413914b0fc4e088372e5b4e Mon Sep 17 00:00:00 2001 From: jNullj <15849761+jNullj@users.noreply.github.com> Date: Fri, 25 Aug 2023 23:27:07 +0300 Subject: [PATCH 6/8] Improve code readability --- src/core/Config.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/Config.cpp b/src/core/Config.cpp index f78e88abbf..fa74755b43 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -533,8 +533,7 @@ QPair Config::defaultConfigFiles() // On case-sensitive Operating Systems, force use of lowercase app directories configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/keepassxc"; // Qt does not support XDG_STATE_HOME yet, change this once XDG_STATE_HOME is added - QString xdgStateHome; - xdgStateHome = QFile::decodeName(qgetenv("XDG_STATE_HOME")); + QString xdgStateHome = QFile::decodeName(qgetenv("XDG_STATE_HOME")); if (!xdgStateHome.startsWith(u'/')) { xdgStateHome.clear(); // spec says relative paths should be ignored } From d77ef9d4f71759d216f2ca9e04c1db3fdb038dae Mon Sep 17 00:00:00 2001 From: jNullj <15849761+jNullj@users.noreply.github.com> Date: Fri, 25 Aug 2023 23:32:47 +0300 Subject: [PATCH 7/8] Improve performance Only generate oldLocalConfigPath if the local config is missing and the old config path should be checked. Before this commit oldLocalConfigPath would always get generated, while it won't be needed most of the time. --- src/core/Config.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/core/Config.cpp b/src/core/Config.cpp index fa74755b43..9925614d12 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -476,19 +476,21 @@ void Config::init(const QString& configFileName, const QString& localConfigFileN // Upgrade from previous KeePassXC version which stores its config // in ~/.cache on Linux instead of ~/.local/state. // Move file to correct location before continuing. - QString oldLocalConfigPath; - oldLocalConfigPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + "/keepassxc"; - QString suffix; + if (!QFile::exists(localConfigFileName)) { + QString oldLocalConfigPath; + oldLocalConfigPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + "/keepassxc"; + QString suffix; #ifdef QT_DEBUG - suffix = "_debug"; + suffix = "_debug"; #endif - oldLocalConfigPath += QString("/keepassxc%1.ini").arg(suffix); - oldLocalConfigPath = QDir::toNativeSeparators(oldLocalConfigPath); - if (!QFile::exists(localConfigFileName) && QFile::exists(oldLocalConfigPath)) { - QDir().mkpath(QFileInfo(localConfigFileName).absolutePath()); - QFile::copy(oldLocalConfigPath, localConfigFileName); - QFile::remove(oldLocalConfigPath); - QDir().rmdir(QFileInfo(oldLocalConfigPath).absolutePath()); + oldLocalConfigPath += QString("/keepassxc%1.ini").arg(suffix); + oldLocalConfigPath = QDir::toNativeSeparators(oldLocalConfigPath); + if (QFile::exists(oldLocalConfigPath)) { + QDir().mkpath(QFileInfo(localConfigFileName).absolutePath()); + QFile::copy(oldLocalConfigPath, localConfigFileName); + QFile::remove(oldLocalConfigPath); + QDir().rmdir(QFileInfo(oldLocalConfigPath).absolutePath()); + } } #endif From 85a2b740ffd2423a30d90dd9e31e2d77ac3f54aa Mon Sep 17 00:00:00 2001 From: jNullj <15849761+jNullj@users.noreply.github.com> Date: Sat, 26 Aug 2023 19:14:28 +0300 Subject: [PATCH 8/8] Improve code readability --- src/core/Config.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 9925614d12..a5ab7e2b62 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -477,8 +477,8 @@ void Config::init(const QString& configFileName, const QString& localConfigFileN // in ~/.cache on Linux instead of ~/.local/state. // Move file to correct location before continuing. if (!QFile::exists(localConfigFileName)) { - QString oldLocalConfigPath; - oldLocalConfigPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + "/keepassxc"; + QString oldLocalConfigPath = + QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + "/keepassxc"; QString suffix; #ifdef QT_DEBUG suffix = "_debug";