From 725e32250ba46b3cfa11d9093cb25ce6c9e8babf Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 26 Mar 2023 11:02:23 +0200 Subject: [PATCH] fix: Move config files to XDG_CONFIG_HOME (#993) This pull request changes Config Directories on Linux to only include the XDG_CONFIG_HOME directory, as opposed to all directories in XDG_DATA_DIRS before (introduced in https://github.com/WerWolv/ImHex/pull/644/files#diff-c1a4d2b63fed168a9a3568944e9cadeae096f2ddcec3649e4a9b2d29fd104be0L162-L166). Reasons: - This changes the location of the config file to the standard directory meant for configurations - This prevents the config file from being read/written in system locations, like /usr/share This PR also includes a migration task that will run on Linux and move config/GUI dimensions to the new directory as a bonus, as discussed on discord, it writes the logs to a Data directory instead of a Config directory --- lib/libimhex/include/hex/helpers/fs.hpp | 3 ++ lib/libimhex/source/helpers/fs.cpp | 16 ++-------- main/source/init/tasks.cpp | 41 +++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/lib/libimhex/include/hex/helpers/fs.hpp b/lib/libimhex/include/hex/helpers/fs.hpp index c3859927e..d970a5935 100644 --- a/lib/libimhex/include/hex/helpers/fs.hpp +++ b/lib/libimhex/include/hex/helpers/fs.hpp @@ -48,4 +48,7 @@ namespace hex::fs { std::vector getDefaultPaths(ImHexPath path, bool listNonExisting = false); + // temporarily expose these for the migration function + std::vector getDataPaths(); + std::vector appendPath(std::vector paths, const std::fs::path &folder); } \ No newline at end of file diff --git a/lib/libimhex/source/helpers/fs.cpp b/lib/libimhex/source/helpers/fs.cpp index af59cdf16..f48432513 100644 --- a/lib/libimhex/source/helpers/fs.cpp +++ b/lib/libimhex/source/helpers/fs.cpp @@ -73,7 +73,7 @@ namespace hex::fs { return result == NFD_OKAY; } - static std::vector getDataPaths() { + std::vector getDataPaths() { std::vector paths; #if defined(OS_WINDOWS) @@ -131,17 +131,7 @@ namespace hex::fs { #elif defined(OS_MACOS) return getDataPaths(); #elif defined(OS_LINUX) - std::vector paths; - - paths.push_back(xdg::DataHomeDir()); - - auto dataDirs = xdg::DataDirs(); - std::copy(dataDirs.begin(), dataDirs.end(), std::back_inserter(paths)); - - for (auto &path : paths) - path = path / "imhex"; - - return paths; + return {xdg::ConfigHomeDir() / "imhex"}; #endif } @@ -177,7 +167,7 @@ namespace hex::fs { result = appendPath(getDataPaths(), "encodings"); break; case ImHexPath::Logs: - result = appendPath(getConfigPaths(), "logs"); + result = appendPath(getDataPaths(), "logs"); break; case ImHexPath::Plugins: result = appendPath(getPluginPaths(), "plugins"); diff --git a/main/source/init/tasks.cpp b/main/source/init/tasks.cpp index 059168133..a080bb1d5 100644 --- a/main/source/init/tasks.cpp +++ b/main/source/init/tasks.cpp @@ -121,6 +121,44 @@ namespace hex::init { return result; } + bool migrateConfig(){ + + // check if there is a new config in folder + auto configPaths = hex::fs::getDefaultPaths(hex::fs::ImHexPath::Config, false); + // There should always be exactly one config path on Linux + std::fs::path newConfigPath = configPaths[0]; + wolv::io::File newConfigFile(newConfigPath / "settings.json", wolv::io::File::Mode::Read); + if (!newConfigFile.isValid()) { + + // find an old config + std::fs::path oldConfigPath; + for(auto dir : hex::fs::appendPath(hex::fs::getDataPaths(), "config")) { + wolv::io::File oldConfigFile(dir / "settings.json", wolv::io::File::Mode::Read); + if (oldConfigFile.isValid()) { + oldConfigPath = dir; + break; + } + } + + if (!oldConfigPath.empty()) { + // move it to new location + auto configPaths = hex::fs::getDefaultPaths(hex::fs::ImHexPath::Config, false); + // There should always be exactly one config path on Linux + std::fs::path newConfigPath = configPaths[0]; + log::info("Found config file in {} ! Migrating to {}", oldConfigPath.string(), newConfigPath.string()); + + std::fs::rename(oldConfigPath / "settings.json", newConfigPath / "settings.json"); + wolv::io::File oldIniFile(oldConfigPath / "interface.ini", wolv::io::File::Mode::Read); + if (oldIniFile.isValid()) { + std::fs::rename(oldConfigPath / "interface.ini", newConfigPath / "interface.ini"); + } + + std::fs::remove(oldConfigPath); + } + } + return true; + } + static bool loadFontsImpl(bool loadUnicode) { float fontSize = ImHexApi::System::getFontSize(); @@ -436,6 +474,9 @@ namespace hex::init { return { { "Setting up environment", setupEnvironment, false }, { "Creating directories", createDirectories, false }, + #if defined(OS_LINUX) + { "Migrate config to .config", migrateConfig, false }, + #endif { "Loading settings", loadSettings, false }, { "Loading plugins", loadPlugins, false }, { "Checking for updates", checkForUpdates, true },