aboutsummaryrefslogtreecommitdiffstats
path: root/src/notmuchworker.h
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-08 10:16:25 +0200
committerDanilo M. <danix@danix.xyz>2026-08-08 10:16:25 +0200
commitbb3e119a55345e997efe80ec275e67acf7a04851 (patch)
tree2d8ce8eca66685e34efe225804b2678fb169f833 /src/notmuchworker.h
parente0595d421c2327ae44ec7af3940ec6ef3d966eae (diff)
downloadqtmaildir-bb3e119a55345e997efe80ec275e67acf7a04851.tar.gz
qtmaildir-bb3e119a55345e997efe80ec275e67acf7a04851.zip
feat(worker): load a thread as a reply tree with per-message depth
loadThread could not be extended to do this. It walks notmuch_query_search_messages, and a message obtained that way returns NULL from notmuch_message_get_replies (notmuch.h:1617-1628), so that walk cannot produce reply depth at all. The tree comes from notmuch_thread_get_toplevel_messages instead, and the pane keeps the flat list it wants. walkReplies takes raw notmuch_message_t*, against this file's rule that every handle is RAII-owned. Messages reached through a thread are freed with it (notmuch.h:1637), so an NmMessage wrapper would destroy memory the thread frees again. The NmThread in the caller is what keeps them alive. Every message in the thread gets a node regardless of the query: the list is where the reply count is read, and hiding unmatched replies would make that count disagree with the rows under it. Both tests mutation-checked. Flattening depth fails the depth assertion, and skipping the thread walk fails it too, so neither passes against the two mistakes the notmuch API invites.
Diffstat (limited to 'src/notmuchworker.h')
-rw-r--r--src/notmuchworker.h17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/notmuchworker.h b/src/notmuchworker.h
index 7d6a587..99cad04 100644
--- a/src/notmuchworker.h
+++ b/src/notmuchworker.h
@@ -55,6 +55,21 @@ public slots:
void loadThread(const QString &threadId, const QString &matchQuery,
quint64 generation);
+ /// Loads a thread as a reply TREE, for the message rows in the list.
+ ///
+ /// Separate from loadThread rather than replacing it, for a reason that is
+ /// not stylistic: loadThread walks notmuch_query_search_messages, and a
+ /// message obtained that way returns NULL from
+ /// notmuch_message_get_replies (notmuch.h:1617-1628), so that walk cannot
+ /// produce reply depth at all. The tree has to come from
+ /// notmuch_thread_get_toplevel_messages instead. The message pane still
+ /// wants the flat list; only the list wants the tree.
+ ///
+ /// matchQuery is accepted for signature symmetry with loadThread and is
+ /// deliberately unused: see the comment on the walk in the .cpp.
+ void loadThreadTree(const QString &threadId, const QString &matchQuery,
+ quint64 generation);
+
/// Applies tag changes. Opens the database read-write, applies, and closes
/// immediately: notmuch's write lock is exclusive process-wide, so holding
/// it would block the user's cron `notmuch new`.
@@ -100,6 +115,8 @@ signals:
void threadsReady(const QVector<ThreadSummary> &threads, quint64 generation);
void queryFinished(int totalThreads, quint64 generation);
void threadLoaded(const QVector<MessageRef> &messages, quint64 generation);
+ void threadTreeLoaded(const QVector<MessageNode> &nodes,
+ quint64 generation);
void tagsApplied(const TagChange &change);
void allTagsReady(const QStringList &tags, quint64 generation);