diff --git a/CHANGELOG.md b/CHANGELOG.md index 373c4925..ebef9fd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ - Minor: Mentions of FrankerFaceZ and BetterTTV in settings are standardized as such. (#5698) - Minor: Emote names are no longer duplicated when using smarter emote completion. (#5705) - Minor: Added a setting to hide the scrollbar thumb (the handle you can drag). Hiding the scrollbar thumb will disable mouse click & drag interactions in the scrollbar. (#5731) +- Minor: The window layout is now backed up like the other settings. (#5647) - Bugfix: Fixed tab move animation occasionally failing to start after closing a tab. (#5426, #5612) - Bugfix: If a network request errors with 200 OK, Qt's error code is now reported instead of the HTTP status. (#5378) - Bugfix: Fixed restricted users usernames not being clickable. (#5405) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 61c19e01..cfd593b8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -494,6 +494,7 @@ set(SOURCE_FILES util/DisplayBadge.cpp util/DisplayBadge.hpp util/Expected.hpp + util/FilesystemHelpers.hpp util/FormatTime.cpp util/FormatTime.hpp util/FunctionEventFilter.cpp diff --git a/src/singletons/WindowManager.cpp b/src/singletons/WindowManager.cpp index 75d09bde..9d3be8ca 100644 --- a/src/singletons/WindowManager.cpp +++ b/src/singletons/WindowManager.cpp @@ -10,6 +10,7 @@ #include "singletons/Settings.hpp" #include "singletons/Theme.hpp" #include "util/CombinePath.hpp" +#include "util/FilesystemHelpers.hpp" #include "util/SignalListener.hpp" #include "widgets/AccountSwitchPopup.hpp" #include "widgets/dialogs/SettingsDialog.hpp" @@ -21,6 +22,7 @@ #include "widgets/splits/SplitContainer.hpp" #include "widgets/Window.hpp" +#include #include #include #include @@ -516,19 +518,33 @@ void WindowManager::save() document.setObject(obj); // save file - QSaveFile file(this->windowLayoutFilePath); - file.open(QIODevice::WriteOnly | QIODevice::Truncate); + std::error_code ec; + pajlada::Settings::Backup::saveWithBackup( + qStringToStdPath(this->windowLayoutFilePath), + {.enabled = true, .numSlots = 9}, + [&](const auto &path, auto &ec) { + QSaveFile file(stdPathToQString(path)); + if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) + { + ec = std::make_error_code(std::errc::io_error); + return; + } - QJsonDocument::JsonFormat format = -#ifdef _DEBUG - QJsonDocument::JsonFormat::Compact -#else - (QJsonDocument::JsonFormat)0 -#endif - ; + file.write(document.toJson(QJsonDocument::Indented)); + if (!file.commit() || file.error() != QFile::NoError) + { + ec = std::make_error_code(std::errc::io_error); + } + }, + ec); - file.write(document.toJson(format)); - file.commit(); + if (ec) + { + // TODO(Qt 6.5): drop fromStdString + qCWarning(chatterinoWindowmanager) + << "Failed to save windowlayout" + << QString::fromStdString(ec.message()); + } } void WindowManager::sendAlert() diff --git a/src/util/FilesystemHelpers.hpp b/src/util/FilesystemHelpers.hpp new file mode 100644 index 00000000..510e38ec --- /dev/null +++ b/src/util/FilesystemHelpers.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +#include + +namespace chatterino { + +inline QString stdPathToQString(const std::filesystem::path &path) +{ +#ifdef Q_OS_WIN + return QString::fromStdWString(path.native()); +#else + return QString::fromStdString(path.native()); +#endif +} + +inline std::filesystem::path qStringToStdPath(const QString &path) +{ + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + const auto *ptr = reinterpret_cast(path.utf16()); + return {ptr, ptr + path.size()}; +} + +} // namespace chatterino