From c3dd54e390d236b7d68bae456ef39c5fa7fb49d5 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Sat, 15 Aug 2026 15:44:38 +0200 Subject: fix(ui): load a thread that was already displayed when the query ran Running a query blanks the message pane but left m_currentThreadId, m_currentMessageId and m_currentMessageThreadId naming the thread that had been showing. Both selection handlers compare a newly selected row against those to decide whether it is already on display, so a result containing that same thread was recognised as "already showing" and onThreadSelected() was never called. The card painted as selected, the status bar reported one thread, and the pane stayed on the placeholder. This is why it looked like an `id:` query defect. The id is copied out of the details dialog of the message being read, so that thread is current at the moment the query replaces the view. Any query returning a different thread hides the fault entirely. Filed as the unverified half of item 66 and assumed to be the same empty-MessageIdRole failure. It is not: 66's fix was correct and this reproduced against it, so it is recorded as item 96. Four hypotheses were eliminated by measurement first: the row does carry the message id, the account-scoped query does return it, MimeParser parses the reported message (ok, 40701 bytes of HTML), and both real ids resolve bare and quoted. The regression test's first query must open the SAME thread the second one returns; with two different threads it passes against the defect, which is how the first version of it was green. Reverting the fix fails it. Co-Authored-By: Claude Opus 5 --- src/mainwindow.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 7ece2f3..2858514 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2230,6 +2230,21 @@ void MainWindow::runQuery(FlatResult flat, AccountScope scope) m_messageView->clear(); showPlaceholderPane(); + // Cleared WITH the pane, not merely alongside it. These three name what the + // pane is showing, and both selection handlers use them to decide whether a + // newly selected row is already displayed. Left set across a query they + // describe a pane that was just blanked, so a result containing that same + // thread is recognised as "already showing" and never loaded. + // + // That is not a corner case, it is the ordinary way an `id:` query is run: + // the id is copied out of the details dialog of the message being read, so + // the thread is current at the moment the query replaces the view, and its + // one card opens onto the placeholder. A query returning any OTHER thread + // hides it, which is why it took a screenshot to find. + m_currentThreadId.clear(); + m_currentMessageId.clear(); + m_currentMessageThreadId.clear(); + // Undo entries refer to rows that are about to be discarded. The model // update they invert would be a no-op against the new result set, leaving // undo half-applied: the database would change and the list would not. -- cgit v1.2.3