From 01194fa2c48019f1dcbdfefac94f8fd5f8e38122 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Fri, 7 Aug 2026 19:17:59 +0200 Subject: feat(sync): sync only the accounts with unsynced edits A sync ran mbsync -a regardless of what changed, so tagging mail in one account fetched all of them. The account set was not a parameter anywhere on the path: MailSync::start() took no arguments and the script hardcoded -a, so nothing between a tag edit and mbsync carried which account changed. Track which accounts have edits and pass their mbsync channels through to the script, which now takes channel names and falls back to -a when given none. An empty set means all accounts, per the request: a sync with nothing pending is a fetch, and narrowing that to wherever the last edit landed would quietly stop collecting mail everywhere else. The channel is a new optional per-account key rather than the section key. The two names genuinely diverge, because a QSettings section key may carry dots that the channel does not, and mbsync treats an unknown channel as fatal rather than skipping it, so key-as-channel would fail those accounts' syncs outright rather than degrade. It defaults to the key, so accounts whose two names already agree need no config change. The edited-account set is deliberately not netted the way the pending-edit map is: that map tracks the index, where a tag removed and re-added leaves nothing outstanding, while this tracks the mail store, where both writes have already renamed files that mbsync still has to propagate. It is also snapshotted before flushHeldEdits(), which inserts into it synchronously rather than on a queued reply, so a successful sync cannot clear accounts whose edits it never carried. Closes item 49. Co-Authored-By: Claude Opus 5 --- src/mailsync.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/mailsync.h') diff --git a/src/mailsync.h b/src/mailsync.h index 3c0d616..f83b526 100644 --- a/src/mailsync.h +++ b/src/mailsync.h @@ -21,6 +21,7 @@ #include #include #include +#include /// Which half of the sync script is running. /// @@ -84,7 +85,15 @@ public: /// Returns false if unavailable or already running. A true return means the /// process was handed to the event loop, not that it launched successfully: /// a missing binary surfaces asynchronously through finished(false, ...). - bool start(); + /// + /// \p channels names the mbsync channels to sync, appended to the + /// configured command as separate arguments. Empty, the default, appends + /// nothing and leaves the script to sync everything: a sync with nothing + /// pending is a fetch, and fetching only the account that happened to hold + /// the last edit would silently stop collecting mail for the others. + /// Blank entries are dropped rather than passed, since mbsync reads an + /// empty argument as a channel name and fails the whole run on it. + bool start(const QStringList &channels = {}); QString log() const { return m_log; } -- cgit v1.2.3