diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-14 18:25:03 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-14 18:25:03 +0200 |
| commit | 86074f40121466798cdd64e07a00db2542543c52 (patch) | |
| tree | 96517aeee0a8a6bb072a3e7d5e0eda7651423fba /src/mainwindow.cpp | |
| parent | 1c479f2834533938d8055146c75fe7cbe79a8cd0 (diff) | |
| download | qtmaildir-86074f40121466798cdd64e07a00db2542543c52.tar.gz qtmaildir-86074f40121466798cdd64e07a00db2542543c52.zip | |
fix(startup): raise the config-problem modal outside the constructor
showWarnings() did two separable things and one of them could not be
reached from a test. It set the status label, which is harmless, and it
raised a QMessageBox from the MainWindow constructor, which under the
offscreen platform nothing can dismiss: the constructor never returned
and the suite hung with no output, reading as an infrastructure failure
rather than a test one.
It splits in two. applyWarnings() keeps the status label and stays in
the constructor. configProblems() returns the list, and main.cpp raises
the dialog after show(), which also gives it a visible parent to sit on.
The distinction between warnings and problems is preserved exactly: a
keybinding being ignored interrupts startup, "no sync command
configured" does not.
The warning path now has its first test, using the config shape that
caused the original hang. Mutation checked by putting the modal back in
the constructor: the test times out at 124 rather than failing, which is
the behaviour this removes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'src/mainwindow.cpp')
| -rw-r--r-- | src/mainwindow.cpp | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index bf6fc79..ee559fe 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -384,7 +384,10 @@ MainWindow::MainWindow(const Config &config, QWidget *parent) // object name, so they must already exist or their position is dropped. restoreUiState(); wireWorker(); - showWarnings(); + // Sets the status label only. The modal that used to live here is raised + // by the caller after show(), because a modal in a constructor cannot be + // dismissed under the offscreen platform and hung the whole suite. + applyWarnings(); // No window-wide event filter: QAction shortcuts are dispatched before the // focused widget sees the key, so they beat QAbstractItemView's @@ -1688,7 +1691,7 @@ void MainWindow::runSearchFromPane(const QString &query, runCurrentQuery(); } -void MainWindow::showWarnings() +void MainWindow::applyWarnings() { const QStringList warnings = m_config.warnings() + m_keyMap.warnings(); if (warnings.isEmpty()) @@ -1697,18 +1700,16 @@ void MainWindow::showWarnings() // Non-fatal: the app runs degraded rather than refusing to start. m_statusLabel->setText( tr("%n configuration warning(s)", "", warnings.size())); +} +QStringList MainWindow::configProblems() const +{ // Interrupt startup only for things that are actually wrong. Every KeyMap // warning qualifies (each one means a binding the user wrote is being // ignored), but a Config notice such as "no sync command configured" does // not: nothing is broken, the feature is simply off, and a modal on every // launch teaches the user to dismiss dialogs unread. - const QStringList problems = m_config.problems() + m_keyMap.warnings(); - if (problems.isEmpty()) - return; - - QMessageBox::warning(this, tr("Configuration problems"), - problems.join(QLatin1Char('\n'))); + return m_config.problems() + m_keyMap.warnings(); } void MainWindow::buildSavedQueryRow(QWidget *parent, QVBoxLayout *layout) |
