|  | 
| 57 | 57 | #include <QThread> | 
| 58 | 58 | #include <QTimer> | 
| 59 | 59 | #include <QTranslator> | 
|  | 60 | +#include <QWindow> | 
| 60 | 61 | 
 | 
| 61 | 62 | #if defined(QT_STATIC) | 
| 62 | 63 | #include <QtPlugin> | 
| @@ -255,6 +256,8 @@ void BitcoinApplication::createOptionsModel(bool resetSettings) | 
| 255 | 256 | void BitcoinApplication::createWindow(const NetworkStyle *networkStyle) | 
| 256 | 257 | { | 
| 257 | 258 |     window = new BitcoinGUI(node(), networkStyle, nullptr); | 
|  | 259 | +    connect(window, &BitcoinGUI::quitRequested, this, &BitcoinApplication::requestShutdown); | 
|  | 260 | + | 
| 258 | 261 |     pollShutdownTimer = new QTimer(window); | 
| 259 | 262 |     connect(pollShutdownTimer, &QTimer::timeout, window, &BitcoinGUI::detectShutdown); | 
| 260 | 263 | } | 
| @@ -289,7 +292,7 @@ void BitcoinApplication::startThread() | 
| 289 | 292 | 
 | 
| 290 | 293 |     /*  communication to and from thread */ | 
| 291 | 294 |     connect(&m_executor.value(), &InitExecutor::initializeResult, this, &BitcoinApplication::initializeResult); | 
| 292 |  | -    connect(&m_executor.value(), &InitExecutor::shutdownResult, this, &BitcoinApplication::shutdownResult); | 
|  | 295 | +    connect(&m_executor.value(), &InitExecutor::shutdownResult, this, &QCoreApplication::quit); | 
| 293 | 296 |     connect(&m_executor.value(), &InitExecutor::runawayException, this, &BitcoinApplication::handleRunawayException); | 
| 294 | 297 |     connect(this, &BitcoinApplication::requestedInitialize, &m_executor.value(), &InitExecutor::initialize); | 
| 295 | 298 |     connect(this, &BitcoinApplication::requestedShutdown, &m_executor.value(), &InitExecutor::shutdown); | 
| @@ -320,13 +323,17 @@ void BitcoinApplication::requestInitialize() | 
| 320 | 323 | 
 | 
| 321 | 324 | void BitcoinApplication::requestShutdown() | 
| 322 | 325 | { | 
|  | 326 | +    for (const auto w : QGuiApplication::topLevelWindows()) { | 
|  | 327 | +        w->hide(); | 
|  | 328 | +    } | 
|  | 329 | + | 
| 323 | 330 |     // Show a simple window indicating shutdown status | 
| 324 | 331 |     // Do this first as some of the steps may take some time below, | 
| 325 | 332 |     // for example the RPC console may still be executing a command. | 
| 326 | 333 |     shutdownWindow.reset(ShutdownWindow::showShutdownWindow(window)); | 
| 327 | 334 | 
 | 
| 328 | 335 |     qDebug() << __func__ << ": Requesting shutdown"; | 
| 329 |  | -    window->hide(); | 
|  | 336 | + | 
| 330 | 337 |     // Must disconnect node signals otherwise current thread can deadlock since | 
| 331 | 338 |     // no event loop is running. | 
| 332 | 339 |     window->unsubscribeFromCoreSignals(); | 
| @@ -406,15 +413,10 @@ void BitcoinApplication::initializeResult(bool success, interfaces::BlockAndHead | 
| 406 | 413 |         pollShutdownTimer->start(SHUTDOWN_POLLING_DELAY); | 
| 407 | 414 |     } else { | 
| 408 | 415 |         Q_EMIT splashFinished(); // Make sure splash screen doesn't stick around during shutdown | 
| 409 |  | -        quit(); // Exit first main loop invocation | 
|  | 416 | +        requestShutdown(); | 
| 410 | 417 |     } | 
| 411 | 418 | } | 
| 412 | 419 | 
 | 
| 413 |  | -void BitcoinApplication::shutdownResult() | 
| 414 |  | -{ | 
| 415 |  | -    quit(); // Exit second main loop invocation after shutdown finished | 
| 416 |  | -} | 
| 417 |  | - | 
| 418 | 420 | void BitcoinApplication::handleRunawayException(const QString &message) | 
| 419 | 421 | { | 
| 420 | 422 |     QMessageBox::critical( | 
| @@ -743,8 +745,6 @@ int GuiMain(int argc, char* argv[]) | 
| 743 | 745 | #if defined(Q_OS_WIN) | 
| 744 | 746 |             WinShutdownMonitor::registerShutdownBlockReason(QObject::tr("%1 didn't yet exit safely…").arg(PACKAGE_NAME), (HWND)app.getMainWinId()); | 
| 745 | 747 | #endif | 
| 746 |  | -            app.exec(); | 
| 747 |  | -            app.requestShutdown(); | 
| 748 | 748 |             app.exec(); | 
| 749 | 749 |             rv = app.getReturnValue(); | 
| 750 | 750 |         } else { | 
|  | 
0 commit comments