From 88fc261fc423ce6879ba2f3e380469e64935bf6b Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 20 Mar 2021 01:28:33 +0200 Subject: [PATCH 1/5] qt: Add BitcoinGUI::hideAll() --- src/qt/bitcoingui.cpp | 8 ++++++++ src/qt/bitcoingui.h | 3 +++ 2 files changed, 11 insertions(+) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 6677c9e3b59..d2e5a388955 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -1395,6 +1395,14 @@ void BitcoinGUI::showModalOverlay() modalOverlay->toggleVisibility(); } +void BitcoinGUI::hideAll() +{ + trayIconMenu->clear(); + trayIcon->hide(); + rpcConsole->hide(); + hide(); +} + static bool ThreadSafeMessageBox(BitcoinGUI* gui, const bilingual_str& message, const std::string& caption, unsigned int style) { bool modal = (style & CClientUIInterface::MODAL); diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 147f19e68df..220aff8dd24 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -319,6 +319,9 @@ public Q_SLOTS: void showProgress(const QString &title, int nProgress); void showModalOverlay(); + + /** Hide all windows and tray icon. */ + void hideAll(); }; class UnitDisplayStatusBarControl : public QLabel From 7a1d449f82a84881ca36109334bd3f37270e5796 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 20 Mar 2021 01:30:00 +0200 Subject: [PATCH 2/5] qt: Use BitcoinGUI::hideAll() --- src/qt/bitcoin.cpp | 2 +- src/qt/bitcoingui.cpp | 14 -------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 791a29f7a00..c2215b2fb87 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -340,7 +340,7 @@ void BitcoinApplication::requestShutdown() qDebug() << __func__ << ": Requesting shutdown"; startThread(); - window->hide(); + window->hideAll(); // Must disconnect node signals otherwise current thread can deadlock since // no event loop is running. window->unsubscribeFromCoreSignals(); diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index d2e5a388955..34de3ac71b2 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -228,8 +228,6 @@ BitcoinGUI::~BitcoinGUI() QSettings settings; settings.setValue("MainWindowGeometry", saveGeometry()); - if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu) - trayIcon->hide(); #ifdef Q_OS_MAC delete m_app_nap_inhibitor; delete appMenuBar; @@ -376,8 +374,6 @@ void BitcoinGUI::createActions() connect(toggleHideAction, &QAction::triggered, this, &BitcoinGUI::toggleHidden); connect(showHelpMessageAction, &QAction::triggered, this, &BitcoinGUI::showHelpMessageClicked); connect(openRPCConsoleAction, &QAction::triggered, this, &BitcoinGUI::showDebugWindow); - // prevents an open debug window from becoming stuck/unusable on client shutdown - connect(quitAction, &QAction::triggered, rpcConsole, &QWidget::hide); #ifdef ENABLE_WALLET if(walletFrame) @@ -625,11 +621,6 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel, interfaces::BlockAndH } else { // Disable possibility to show main window via action toggleHideAction->setEnabled(false); - if(trayIconMenu) - { - // Disable context menu on tray icon - trayIconMenu->clear(); - } // Propagate cleared model to child objects rpcConsole->setClientModel(nullptr); #ifdef ENABLE_WALLET @@ -1167,9 +1158,6 @@ void BitcoinGUI::closeEvent(QCloseEvent *event) { if(!clientModel->getOptionsModel()->getMinimizeOnClose()) { - // close rpcConsole in case it was open to make some space for the shutdown window - rpcConsole->close(); - QApplication::quit(); } else @@ -1363,8 +1351,6 @@ void BitcoinGUI::detectShutdown() { if (m_node.shutdownRequested()) { - if(rpcConsole) - rpcConsole->hide(); qApp->quit(); } } From 753103dd53a00ba43dff67429175af628e264613 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 20 Mar 2021 01:31:20 +0200 Subject: [PATCH 3/5] qt: Make requestShutdown() a slot --- src/qt/bitcoin.cpp | 7 +++---- src/qt/bitcoin.h | 4 ++-- src/qt/bitcoingui.cpp | 7 ++++--- src/qt/bitcoingui.h | 1 + src/qt/optionsdialog.cpp | 3 ++- src/qt/optionsdialog.h | 1 + 6 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index c2215b2fb87..85ff8ac02ba 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -257,6 +257,7 @@ void BitcoinApplication::createOptionsModel(bool resetSettings) void BitcoinApplication::createWindow(const NetworkStyle *networkStyle) { window = new BitcoinGUI(node(), platformStyle, networkStyle, nullptr); + connect(window, &BitcoinGUI::quitClicked, this, &BitcoinApplication::requestShutdown); pollShutdownTimer = new QTimer(window); connect(pollShutdownTimer, &QTimer::timeout, window, &BitcoinGUI::detectShutdown); @@ -406,13 +407,13 @@ void BitcoinApplication::initializeResult(bool success, interfaces::BlockAndHead pollShutdownTimer->start(200); } else { Q_EMIT splashFinished(); // Make sure splash screen doesn't stick around during shutdown - quit(); // Exit first main loop invocation + requestShutdown(); } } void BitcoinApplication::shutdownResult() { - quit(); // Exit second main loop invocation after shutdown finished + quit(); } void BitcoinApplication::handleRunawayException(const QString &message) @@ -616,8 +617,6 @@ int GuiMain(int argc, char* argv[]) #if defined(Q_OS_WIN) WinShutdownMonitor::registerShutdownBlockReason(QObject::tr("%1 didn't yet exit safely...").arg(PACKAGE_NAME), (HWND)app.getMainWinId()); #endif - app.exec(); - app.requestShutdown(); app.exec(); rv = app.getReturnValue(); } else { diff --git a/src/qt/bitcoin.h b/src/qt/bitcoin.h index 69e0a5921e7..96a8655623c 100644 --- a/src/qt/bitcoin.h +++ b/src/qt/bitcoin.h @@ -78,8 +78,6 @@ class BitcoinApplication: public QApplication /// Request core initialization void requestInitialize(); - /// Request core shutdown - void requestShutdown(); /// Get process return value int getReturnValue() const { return returnValue; } @@ -95,6 +93,8 @@ class BitcoinApplication: public QApplication public Q_SLOTS: void initializeResult(bool success, interfaces::BlockAndHeaderTipInfo tip_info); + /// Request core shutdown + void requestShutdown(); void shutdownResult(); /// Handle runaway exceptions. Shows a message box with the problem and quits the program. void handleRunawayException(const QString &message); diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 34de3ac71b2..e01c8abfd2b 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -367,7 +367,7 @@ void BitcoinGUI::createActions() m_mask_values_action->setStatusTip(tr("Mask the values in the Overview tab")); m_mask_values_action->setCheckable(true); - connect(quitAction, &QAction::triggered, qApp, QApplication::quit); + connect(quitAction, &QAction::triggered, this, &BitcoinGUI::quitClicked); connect(aboutAction, &QAction::triggered, this, &BitcoinGUI::aboutClicked); connect(aboutQtAction, &QAction::triggered, qApp, QApplication::aboutQt); connect(optionsAction, &QAction::triggered, this, &BitcoinGUI::optionsClicked); @@ -946,6 +946,7 @@ void BitcoinGUI::openOptionsDialogWithTab(OptionsDialog::Tab tab) OptionsDialog dlg(this, enableWallet); dlg.setCurrentTab(tab); dlg.setModel(clientModel->getOptionsModel()); + connect(&dlg, &OptionsDialog::quitOnReset, this, &BitcoinGUI::quitClicked); dlg.exec(); } @@ -1158,7 +1159,7 @@ void BitcoinGUI::closeEvent(QCloseEvent *event) { if(!clientModel->getOptionsModel()->getMinimizeOnClose()) { - QApplication::quit(); + Q_EMIT quitClicked(); } else { @@ -1351,7 +1352,7 @@ void BitcoinGUI::detectShutdown() { if (m_node.shutdownRequested()) { - qApp->quit(); + Q_EMIT quitClicked(); } } diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 220aff8dd24..ba360474c30 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -211,6 +211,7 @@ class BitcoinGUI : public QMainWindow void openOptionsDialogWithTab(OptionsDialog::Tab tab); Q_SIGNALS: + void quitClicked(); /** Signal raised when a URI was entered or dragged to the GUI */ void receivedURI(const QString &uri); /** Signal raised when RPC console shown */ diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index e6b9488344f..8b801695f62 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -282,7 +282,8 @@ void OptionsDialog::on_resetButton_clicked() /* reset all options and close GUI */ model->Reset(); - QApplication::quit(); + close(); + Q_EMIT quitOnReset(); } } diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h index ba35ff3b67e..f14aec3449b 100644 --- a/src/qt/optionsdialog.h +++ b/src/qt/optionsdialog.h @@ -68,6 +68,7 @@ private Q_SLOTS: Q_SIGNALS: void proxyIpChecks(QValidatedLineEdit *pUiProxyIp, uint16_t nProxyPort); + void quitOnReset(); private: Ui::OptionsDialog *ui; From 9af25492dc9b414925315221063cb5490197a385 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 20 Mar 2021 01:32:18 +0200 Subject: [PATCH 4/5] qt: Factor out requestNodeShutdown() slot --- src/qt/bitcoin.cpp | 13 +++++++++---- src/qt/bitcoin.h | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 85ff8ac02ba..247e36c0d92 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -339,8 +339,6 @@ void BitcoinApplication::requestShutdown() // for example the RPC console may still be executing a command. shutdownWindow.reset(ShutdownWindow::showShutdownWindow(window)); - qDebug() << __func__ << ": Requesting shutdown"; - startThread(); window->hideAll(); // Must disconnect node signals otherwise current thread can deadlock since // no event loop is running. @@ -356,8 +354,7 @@ void BitcoinApplication::requestShutdown() delete clientModel; clientModel = nullptr; - // Request shutdown from core thread - Q_EMIT requestedShutdown(); + requestNodeShutdown(); } void BitcoinApplication::initializeResult(bool success, interfaces::BlockAndHeaderTipInfo tip_info) @@ -411,6 +408,14 @@ void BitcoinApplication::initializeResult(bool success, interfaces::BlockAndHead } } +void BitcoinApplication::requestNodeShutdown() +{ + qDebug() << __func__ << ": Requesting shutdown"; + startThread(); + // Request shutdown from core thread + Q_EMIT requestedShutdown(); +} + void BitcoinApplication::shutdownResult() { quit(); diff --git a/src/qt/bitcoin.h b/src/qt/bitcoin.h index 96a8655623c..1c065f82bb7 100644 --- a/src/qt/bitcoin.h +++ b/src/qt/bitcoin.h @@ -95,6 +95,7 @@ public Q_SLOTS: void initializeResult(bool success, interfaces::BlockAndHeaderTipInfo tip_info); /// Request core shutdown void requestShutdown(); + void requestNodeShutdown(); void shutdownResult(); /// Handle runaway exceptions. Shows a message box with the problem and quits the program. void handleRunawayException(const QString &message); From 84a9a7ce4ddf6627afca42e6ed6fd8ead55503f9 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 9 May 2020 07:13:10 +0300 Subject: [PATCH 5/5] qt: Do not block GUI thread in RPCConsole --- src/qt/bitcoin.cpp | 5 ++--- src/qt/bitcoingui.cpp | 2 ++ src/qt/bitcoingui.h | 1 + src/qt/rpcconsole.cpp | 2 +- src/qt/rpcconsole.h | 1 + 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 247e36c0d92..aa18549a7b8 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -258,6 +258,7 @@ void BitcoinApplication::createWindow(const NetworkStyle *networkStyle) { window = new BitcoinGUI(node(), platformStyle, networkStyle, nullptr); connect(window, &BitcoinGUI::quitClicked, this, &BitcoinApplication::requestShutdown); + connect(window, &BitcoinGUI::rpcExecutorThreadFinished, this, &BitcoinApplication::requestNodeShutdown); pollShutdownTimer = new QTimer(window); connect(pollShutdownTimer, &QTimer::timeout, window, &BitcoinGUI::detectShutdown); @@ -353,8 +354,6 @@ void BitcoinApplication::requestShutdown() delete clientModel; clientModel = nullptr; - - requestNodeShutdown(); } void BitcoinApplication::initializeResult(bool success, interfaces::BlockAndHeaderTipInfo tip_info) @@ -404,7 +403,7 @@ void BitcoinApplication::initializeResult(bool success, interfaces::BlockAndHead pollShutdownTimer->start(200); } else { Q_EMIT splashFinished(); // Make sure splash screen doesn't stick around during shutdown - requestShutdown(); + requestNodeShutdown(); } } diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index e01c8abfd2b..bae0902d281 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -98,6 +98,8 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const PlatformStyle *_platformSty updateWindowTitle(); rpcConsole = new RPCConsole(node, _platformStyle, nullptr); + connect(rpcConsole, &RPCConsole::executorThreadFinished, this, &BitcoinGUI::rpcExecutorThreadFinished); + helpMessageDialog = new HelpMessageDialog(this, false); #ifdef ENABLE_WALLET if(enableWallet) diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index ba360474c30..82cb7258cd8 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -212,6 +212,7 @@ class BitcoinGUI : public QMainWindow Q_SIGNALS: void quitClicked(); + void rpcExecutorThreadFinished(); /** Signal raised when a URI was entered or dragged to the GUI */ void receivedURI(const QString &uri); /** Signal raised when RPC console shown */ diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index b2582198941..fa2e48981f1 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -707,8 +707,8 @@ void RPCConsole::setClientModel(ClientModel *model, int bestblock_height, int64_ } if (!model) { // Client model is being set to 0, this means shutdown() is about to be called. + connect(&thread, &QThread::finished, this, &RPCConsole::executorThreadFinished); thread.quit(); - thread.wait(); } } diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index b9806e40c97..d8f01262d0e 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -134,6 +134,7 @@ public Q_SLOTS: Q_SIGNALS: // For RPC command executor void cmdRequest(const QString &command, const WalletModel* wallet_model); + void executorThreadFinished(); private: struct TranslatedStrings {