aboutsummaryrefslogtreecommitdiffstats
path: root/src/mainwindow.h
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-31 11:26:52 +0100
committerDanilo M. <danix@danix.xyz>2026-10-31 11:26:52 +0100
commit467fa84fd851459d5d9c9e5297e2500e938f0a18 (patch)
tree392d0237cac273a6a07db11b120a8a453e8e8ff6 /src/mainwindow.h
parent9ae9473acdb7cb3310c3028765cc4b30fedfce27 (diff)
downloadqtmaildir-467fa84fd851459d5d9c9e5297e2500e938f0a18.tar.gz
qtmaildir-467fa84fd851459d5d9c9e5297e2500e938f0a18.zip
fix: keep bulk tag actions linear, and say when they land
Select all on a 10k-row search, then Archive, froze the window with one CPU pinned. gdb on the live process showed the UI thread cubic before the write was ever sent: each optimistic row write emitted dataChanged, whose handler refreshed the action labels by walking the whole selection, and each step of that walk looked the message up with a linear scan of every thread. ThreadListModel now answers id lookups from a lazily rebuilt hash, invalidated by its own structural signals and by hand at the two in-place id changes. MainWindow::batchModelWrites() holds the label refresh while a loop of optimistic writes runs, then refreshes once. Two list membership tests became sets. The announcement also used to fade on a timer whether or not the write had landed. It now reads "applying" until a round trip through the worker's queue says the write has run, then "done". An error takes the label back from a late "done". Item 211. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'src/mainwindow.h')
-rw-r--r--src/mainwindow.h6
1 files changed, 6 insertions, 0 deletions
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 87ed171..868964a 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -1179,6 +1179,10 @@ private:
/// something, the same rule refreshUnreadAction() applies to the label.
void refreshTrashActions();
+ /// Runs a loop of optimistic model writes with the dataChanged-driven
+ /// action refresh held, then refreshes once (item 211).
+ void batchModelWrites(const std::function<void()> &writes);
+
/// Whether every selected row's file already sits in its account's trash
/// folder. Empty selection answers false.
///
@@ -1209,6 +1213,8 @@ private:
/// for exit has finished. Stops closeEvent asking a second time, and is
/// what lets the deferred close through.
bool m_closeApproved = false;
+ bool m_batchingModelWrites = false; ///< see batchModelWrites()
+ quint64 m_announceTicket = 0; ///< see announceAction()
/// True while a sync started by the exit prompt is running. The window
/// stays open until it finishes: killing the process mid-sync is exactly