diff --git a/src/singletons/WindowManager.cpp b/src/singletons/WindowManager.cpp index aa58ed48a..e75b0278c 100644 --- a/src/singletons/WindowManager.cpp +++ b/src/singletons/WindowManager.cpp @@ -23,6 +23,8 @@ #include #include +#include + #define SETTINGS_FILENAME "/window-layout.json" namespace chatterino { @@ -83,6 +85,14 @@ WindowManager::WindowManager() this->wordFlagsListener_.cb = [this](auto) { this->updateWordTypeMask(); // }; + + this->saveTimer = new QTimer; + + this->saveTimer->setSingleShot(true); + + QObject::connect(this->saveTimer, &QTimer::timeout, [] { + getApp()->windows->save(); // + }); } MessageElementFlags WindowManager::getWordFlags() @@ -357,6 +367,8 @@ void WindowManager::initialize(Settings &settings, Paths &paths) void WindowManager::save() { + log("[WindowManager] Saving"); + assertInGuiThread(); auto app = getApp(); @@ -453,6 +465,13 @@ void WindowManager::sendAlert() QApplication::alert(this->getMainWindow().window(), flashDuration); } +void WindowManager::queueSave() +{ + using namespace std::chrono_literals; + + this->saveTimer->start(10s); +} + void WindowManager::encodeNodeRecusively(SplitNode *node, QJsonObject &obj) { switch (node->getType()) { diff --git a/src/singletons/WindowManager.hpp b/src/singletons/WindowManager.hpp index 9ca3dc879..dc66b0c7f 100644 --- a/src/singletons/WindowManager.hpp +++ b/src/singletons/WindowManager.hpp @@ -77,6 +77,11 @@ public: // or not void sendAlert(); + // Queue up a save in the next 10 seconds + // If a save was already queued up, we reset the to happen in 10 seconds + // again + void queueSave(); + private: void encodeNodeRecusively(SplitContainer::Node *node, QJsonObject &obj); @@ -91,6 +96,8 @@ private: MessageElementFlags wordFlags_{}; pajlada::Settings::SettingListener wordFlagsListener_; + + QTimer *saveTimer; }; } // namespace chatterino diff --git a/src/widgets/BaseWindow.cpp b/src/widgets/BaseWindow.cpp index 6394284e0..5c6df9f54 100644 --- a/src/widgets/BaseWindow.cpp +++ b/src/widgets/BaseWindow.cpp @@ -420,11 +420,22 @@ void BaseWindow::moveTo(QWidget *parent, QPoint point, bool offset) void BaseWindow::resizeEvent(QResizeEvent *) { + // Queue up save because: Window resized + getApp()->windows->queueSave(); + this->moveIntoDesktopRect(this); this->calcButtonsSizes(); } +void BaseWindow::moveEvent(QMoveEvent *event) +{ + // Queue up save because: Window position changed + getApp()->windows->queueSave(); + + BaseWidget::moveEvent(event); +} + void BaseWindow::closeEvent(QCloseEvent *) { this->closing.invoke(); diff --git a/src/widgets/BaseWindow.hpp b/src/widgets/BaseWindow.hpp index 088c07c86..25b12025a 100644 --- a/src/widgets/BaseWindow.hpp +++ b/src/widgets/BaseWindow.hpp @@ -64,6 +64,7 @@ protected: virtual void changeEvent(QEvent *) override; virtual void leaveEvent(QEvent *) override; virtual void resizeEvent(QResizeEvent *) override; + virtual void moveEvent(QMoveEvent *) override; virtual void closeEvent(QCloseEvent *) override; virtual void themeChangedEvent() override; diff --git a/src/widgets/Notebook.cpp b/src/widgets/Notebook.cpp index c56fba8b5..3ec63fc29 100644 --- a/src/widgets/Notebook.cpp +++ b/src/widgets/Notebook.cpp @@ -45,6 +45,9 @@ Notebook::Notebook(QWidget *parent) NotebookTab *Notebook::addPage(QWidget *page, QString title, bool select) { + // Queue up save because: Tab added + getApp()->windows->queueSave(); + auto *tab = new NotebookTab(this); tab->page = page; @@ -72,6 +75,9 @@ NotebookTab *Notebook::addPage(QWidget *page, QString title, bool select) void Notebook::removePage(QWidget *page) { + // Queue up save because: Tab removed + getApp()->windows->queueSave(); + for (int i = 0; i < this->items_.count(); i++) { if (this->items_[i].page == page) { if (this->items_.count() == 1) { @@ -267,6 +273,9 @@ QWidget *Notebook::tabAt(QPoint point, int &index, int maxWidth) void Notebook::rearrangePage(QWidget *page, int index) { + // Queue up save because: Tab rearranged + getApp()->windows->queueSave(); + this->items_.move(this->indexOf(page), index); this->performLayout(true); diff --git a/src/widgets/helper/NotebookTab.cpp b/src/widgets/helper/NotebookTab.cpp index f3f2f7643..8875a4ca6 100644 --- a/src/widgets/helper/NotebookTab.cpp +++ b/src/widgets/helper/NotebookTab.cpp @@ -6,6 +6,7 @@ #include "singletons/Fonts.hpp" #include "singletons/Settings.hpp" #include "singletons/Theme.hpp" +#include "singletons/WindowManager.hpp" #include "util/Clamp.hpp" #include "util/Helpers.hpp" #include "widgets/Notebook.hpp" @@ -146,6 +147,9 @@ const QString &NotebookTab::getTitle() const void NotebookTab::titleUpdated() { + // Queue up save because: Tab title changed + getApp()->windows->queueSave(); + this->updateSize(); this->update(); } diff --git a/src/widgets/splits/Split.cpp b/src/widgets/splits/Split.cpp index 225e526fd..57348be6c 100644 --- a/src/widgets/splits/Split.cpp +++ b/src/widgets/splits/Split.cpp @@ -224,6 +224,9 @@ void Split::setChannel(IndirectChannel newChannel) this->header_->updateRoomModes(); this->channelChanged.invoke(); + + // Queue up save because: Split channel changed + getApp()->windows->queueSave(); } void Split::setModerationMode(bool value) @@ -326,6 +329,9 @@ void Split::keyReleaseEvent(QKeyEvent *event) void Split::resizeEvent(QResizeEvent *event) { + // Queue up save because: Split resized + getApp()->windows->queueSave(); + BaseWidget::resizeEvent(event); this->overlay_->setGeometry(this->rect()); diff --git a/src/widgets/splits/SplitContainer.cpp b/src/widgets/splits/SplitContainer.cpp index 86fc7673a..a4de3e6d1 100644 --- a/src/widgets/splits/SplitContainer.cpp +++ b/src/widgets/splits/SplitContainer.cpp @@ -1,4 +1,5 @@ #include "widgets/splits/SplitContainer.hpp" + #include "Application.hpp" #include "common/Common.hpp" #include "debug/AssertInGuiThread.hpp" @@ -142,6 +143,9 @@ void SplitContainer::insertSplit(Split *split, Direction direction, void SplitContainer::insertSplit(Split *split, Direction direction, Node *relativeTo) { + // Queue up save because: Split added + getApp()->windows->queueSave(); + assertInGuiThread(); split->setContainer(this); @@ -236,6 +240,9 @@ SplitContainer::Position SplitContainer::releaseSplit(Split *split) SplitContainer::Position SplitContainer::deleteSplit(Split *split) { + // Queue up save because: Split removed + getApp()->windows->queueSave(); + assertInGuiThread(); assert(split != nullptr);