summaryrefslogtreecommitdiffstats
path: root/src/mainwindow.h
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-03 16:00:38 +0200
committerDanilo M. <danix@danix.xyz>2026-08-03 16:00:38 +0200
commite6ea00dce8c74bf0d48e769734958a741ca46ef9 (patch)
tree2b56659912cfa1f284faefa2e04d841e9a51852e /src/mainwindow.h
parentec390fb46e1a36d8406dde487228bbb0f348a20a (diff)
downloadqtmaildir-e6ea00dce8c74bf0d48e769734958a741ca46ef9.tar.gz
qtmaildir-e6ea00dce8c74bf0d48e769734958a741ca46ef9.zip
feat: persist window, splitter and column widths
Resizing the window, the splitter or a thread-list column was undone by the next launch. State now round-trips through a separate settings file at ~/.local/state/qtmaildir/uistate.conf, written on close and read at startup. The state file is deliberately not the user's config: a base64 geometry blob does not belong in a hand-edited file, and rewriting that file on exit would drop its comments and key order, which QSettings does not preserve. Two details that are easy to get wrong: QStandardPaths::StateLocation appends both the organization and the application name, and both are "qtmaildir" here, so it resolves to ~/.local/state/qtmaildir/qtmaildir. The path is built from GenericStateLocation instead, matching Config::defaultPath(). Restore runs after buildMenus() rather than at the end of buildUi(): QMainWindow::restoreState() matches toolbars by object name and silently drops the position of one that does not exist yet. Every restore is conditional on a non-empty blob, so a missing or rejected state file leaves the built-in defaults instead of producing a zero-size window. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'src/mainwindow.h')
-rw-r--r--src/mainwindow.h17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 4445894..f4186ff 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -38,6 +38,7 @@ class QLabel;
class QPushButton;
class QComboBox;
class QPlainTextEdit;
+class QSplitter;
class ThreadListModel;
class MessageView;
@@ -63,6 +64,15 @@ public:
/// cid: references from resolving to another's.
static QString cidPrefixForIndex(int index);
+ /// Path of the machine-written UI state file. Deliberately not
+ /// Config::defaultPath(): the config is hand-edited and must never gain a
+ /// base64 geometry blob, nor be rewritten on exit (QSettings does not
+ /// preserve comments or key order).
+ static QString uiStatePath();
+
+protected:
+ void closeEvent(QCloseEvent *event) override;
+
private slots:
void runCurrentQuery();
void onThreadsReady(const QVector<ThreadSummary> &threads, quint64 generation);
@@ -74,6 +84,12 @@ private slots:
private:
void buildUi();
+
+ /// Restores window geometry, splitter and thread-list header widths.
+ /// A missing or rejected blob leaves the buildUi() defaults in place.
+ void restoreUiState();
+ void saveUiState() const;
+
void registerActions();
void buildMenus();
void wireWorker();
@@ -116,6 +132,7 @@ private:
QLineEdit *m_queryEdit = nullptr;
QTableView *m_threadView = nullptr;
+ QSplitter *m_splitter = nullptr;
QComboBox *m_accountBox = nullptr;
QPushButton *m_syncButton = nullptr;
QLabel *m_statusLabel = nullptr;