From c3ca8364b2a8de8c73ecc0c7eed9608bd30e7e02 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 8 Feb 2022 16:19:12 +0200 Subject: [PATCH 01/11] qt, refactor: Replace BitcoinGUI::macosDockIconActivated with a lambda --- src/qt/bitcoingui.cpp | 11 ++++------- src/qt/bitcoingui.h | 3 --- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 0baacfe58c..ca351060fd 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -793,7 +793,10 @@ void BitcoinGUI::createTrayIconMenu() #else // Note: On macOS, the Dock icon is used to provide the tray's functionality. MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance(); - connect(dockIconHandler, &MacDockIconHandler::dockIconClicked, this, &BitcoinGUI::macosDockIconActivated); + connect(dockIconHandler, &MacDockIconHandler::dockIconClicked, [this] { + show(); + activateWindow(); + }); trayIconMenu->setAsDockMenu(); #endif @@ -828,12 +831,6 @@ void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason) toggleHidden(); } } -#else -void BitcoinGUI::macosDockIconActivated() -{ - show(); - activateWindow(); -} #endif void BitcoinGUI::optionsClicked() diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 658ab5a210..ae9cb9f11d 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -305,9 +305,6 @@ public Q_SLOTS: #ifndef Q_OS_MAC /** Handle tray icon clicked */ void trayIconActivated(QSystemTrayIcon::ActivationReason reason); -#else - /** Handle macOS Dock icon clicked */ - void macosDockIconActivated(); #endif /** Show window if hidden, unminimize when minimized, rise when obscured or show if hidden and fToggleHidden is true */ From 66afa286e519deda2fcfd580f190b7af13407e72 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 8 Feb 2022 16:21:45 +0200 Subject: [PATCH 02/11] qt, refactor: Replace BitcoinGUI::trayIconActivated with a lambda --- src/qt/bitcoingui.cpp | 18 ++++++------------ src/qt/bitcoingui.h | 4 ---- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index ca351060fd..dd3e1b41a7 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -789,7 +789,12 @@ void BitcoinGUI::createTrayIconMenu() return; trayIcon->setContextMenu(trayIconMenu.get()); - connect(trayIcon, &QSystemTrayIcon::activated, this, &BitcoinGUI::trayIconActivated); + connect(trayIcon, &QSystemTrayIcon::activated, [this](QSystemTrayIcon::ActivationReason reason) { + if (reason == QSystemTrayIcon::Trigger) { + // Click on system tray icon triggers show/hide of the main window + toggleHidden(); + } + }); #else // Note: On macOS, the Dock icon is used to provide the tray's functionality. MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance(); @@ -822,17 +827,6 @@ void BitcoinGUI::createTrayIconMenu() #endif } -#ifndef Q_OS_MAC -void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason) -{ - if(reason == QSystemTrayIcon::Trigger) - { - // Click on system tray icon triggers show/hide of the main window - toggleHidden(); - } -} -#endif - void BitcoinGUI::optionsClicked() { openOptionsDialogWithTab(OptionsDialog::TAB_MAIN); diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index ae9cb9f11d..896c4c52c6 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -302,10 +302,6 @@ public Q_SLOTS: void showDebugWindowActivateConsole(); /** Show help message dialog */ void showHelpMessageClicked(); -#ifndef Q_OS_MAC - /** Handle tray icon clicked */ - void trayIconActivated(QSystemTrayIcon::ActivationReason reason); -#endif /** Show window if hidden, unminimize when minimized, rise when obscured or show if hidden and fToggleHidden is true */ void showNormalIfMinimized() { showNormalIfMinimized(false); } From 78189daac8d13870ab6ed8421b9ed067cf7ebac5 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 8 Feb 2022 16:27:00 +0200 Subject: [PATCH 03/11] qt, refactor: Fill up trayIconMenu before connections This change is required for the following commits. --- src/qt/bitcoingui.cpp | 48 +++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index dd3e1b41a7..1c497960cb 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -784,33 +784,16 @@ void BitcoinGUI::createTrayIcon() void BitcoinGUI::createTrayIconMenu() { #ifndef Q_OS_MAC - // return if trayIcon is unset (only on non-macOSes) - if (!trayIcon) - return; + if (!trayIcon) return; +#endif // Q_OS_MAC - trayIcon->setContextMenu(trayIconMenu.get()); - connect(trayIcon, &QSystemTrayIcon::activated, [this](QSystemTrayIcon::ActivationReason reason) { - if (reason == QSystemTrayIcon::Trigger) { - // Click on system tray icon triggers show/hide of the main window - toggleHidden(); - } - }); -#else - // Note: On macOS, the Dock icon is used to provide the tray's functionality. - MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance(); - connect(dockIconHandler, &MacDockIconHandler::dockIconClicked, [this] { - show(); - activateWindow(); - }); - trayIconMenu->setAsDockMenu(); -#endif - - // Configuration of the tray icon (or Dock icon) menu + // Configuration of the tray icon (or Dock icon) menu. #ifndef Q_OS_MAC // Note: On macOS, the Dock icon's menu already has Show / Hide action. trayIconMenu->addAction(toggleHideAction); trayIconMenu->addSeparator(); -#endif +#endif // Q_OS_MAC + if (enableWallet) { trayIconMenu->addAction(sendCoinsMenuAction); trayIconMenu->addAction(receiveCoinsMenuAction); @@ -821,10 +804,27 @@ void BitcoinGUI::createTrayIconMenu() } trayIconMenu->addAction(optionsAction); trayIconMenu->addAction(openRPCConsoleAction); -#ifndef Q_OS_MAC // This is built-in on macOS +#ifndef Q_OS_MAC + // Note: On macOS, the Dock icon's menu already has Quit action. trayIconMenu->addSeparator(); trayIconMenu->addAction(quitAction); -#endif + + trayIcon->setContextMenu(trayIconMenu.get()); + connect(trayIcon, &QSystemTrayIcon::activated, [this](QSystemTrayIcon::ActivationReason reason) { + if (reason == QSystemTrayIcon::Trigger) { + // Click on system tray icon triggers show/hide of the main window + toggleHidden(); + } + }); +#else + // Note: On macOS, the Dock icon is used to provide the tray's functionality. + MacDockIconHandler* dockIconHandler = MacDockIconHandler::instance(); + connect(dockIconHandler, &MacDockIconHandler::dockIconClicked, [this] { + show(); + activateWindow(); + }); + trayIconMenu->setAsDockMenu(); +#endif // Q_OS_MAC } void BitcoinGUI::optionsClicked() From ee151d032789fa03daa44ab44dd0fd70e51b145c Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 8 Feb 2022 16:30:23 +0200 Subject: [PATCH 04/11] qt: Drop BitcoinGUI::toggleHideAction member Also dropped useless tooltip. --- src/qt/bitcoingui.cpp | 8 ++------ src/qt/bitcoingui.h | 1 - 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 1c497960cb..ea976302ab 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -315,8 +315,6 @@ void BitcoinGUI::createActions() optionsAction->setStatusTip(tr("Modify configuration options for %1").arg(PACKAGE_NAME)); optionsAction->setMenuRole(QAction::PreferencesRole); optionsAction->setEnabled(false); - toggleHideAction = new QAction(tr("&Show / Hide"), this); - toggleHideAction->setStatusTip(tr("Show or hide the main Window")); encryptWalletAction = new QAction(tr("&Encrypt Wallet…"), this); encryptWalletAction->setStatusTip(tr("Encrypt the private keys that belong to your wallet")); @@ -376,7 +374,6 @@ void BitcoinGUI::createActions() connect(aboutAction, &QAction::triggered, this, &BitcoinGUI::aboutClicked); connect(aboutQtAction, &QAction::triggered, qApp, QApplication::aboutQt); connect(optionsAction, &QAction::triggered, this, &BitcoinGUI::optionsClicked); - 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 @@ -627,8 +624,6 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel, interfaces::BlockAndH trayIcon->setVisible(optionsModel->getShowTrayIcon()); } } else { - // Disable possibility to show main window via action - toggleHideAction->setEnabled(false); if(trayIconMenu) { // Disable context menu on tray icon @@ -788,9 +783,10 @@ void BitcoinGUI::createTrayIconMenu() #endif // Q_OS_MAC // Configuration of the tray icon (or Dock icon) menu. + QAction* show_hide_action{nullptr}; #ifndef Q_OS_MAC // Note: On macOS, the Dock icon's menu already has Show / Hide action. - trayIconMenu->addAction(toggleHideAction); + show_hide_action = trayIconMenu->addAction(tr("Show / &Hide"), this, &BitcoinGUI::toggleHidden); trayIconMenu->addSeparator(); #endif // Q_OS_MAC diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 896c4c52c6..887cf3f33d 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -148,7 +148,6 @@ private: QAction* receiveCoinsAction = nullptr; QAction* receiveCoinsMenuAction = nullptr; QAction* optionsAction = nullptr; - QAction* toggleHideAction = nullptr; QAction* encryptWalletAction = nullptr; QAction* backupWalletAction = nullptr; QAction* changePassphraseAction = nullptr; From fd667e73cd109bbfc14011f8c2c08556648b4c50 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 8 Feb 2022 16:31:43 +0200 Subject: [PATCH 05/11] qt: Make show_hide_action dependent on the main window actual state --- src/qt/bitcoingui.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index ea976302ab..90925b643c 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -786,7 +786,7 @@ void BitcoinGUI::createTrayIconMenu() QAction* show_hide_action{nullptr}; #ifndef Q_OS_MAC // Note: On macOS, the Dock icon's menu already has Show / Hide action. - show_hide_action = trayIconMenu->addAction(tr("Show / &Hide"), this, &BitcoinGUI::toggleHidden); + show_hide_action = trayIconMenu->addAction(QString(), this, &BitcoinGUI::toggleHidden); trayIconMenu->addSeparator(); #endif // Q_OS_MAC @@ -821,6 +821,17 @@ void BitcoinGUI::createTrayIconMenu() }); trayIconMenu->setAsDockMenu(); #endif // Q_OS_MAC + + connect( + // Using QSystemTrayIcon::Context is not reliable. + // See https://bugreports.qt.io/browse/QTBUG-91697 + trayIconMenu.get(), &QMenu::aboutToShow, + [this, show_hide_action] { + if (show_hide_action) show_hide_action->setText( + (!isHidden() && !isMinimized() && !GUIUtil::isObscured(this)) ? + tr("&Hide") : + tr("S&how")); + }); } void BitcoinGUI::optionsClicked() From 58e16035c1fc513fce0b09e02c7d863c63ec990d Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 8 Feb 2022 17:21:04 +0200 Subject: [PATCH 06/11] qt, refactor: Drop BitcoinGUI::{send,receive}CoinsMenuAction members --- src/qt/bitcoingui.cpp | 26 +++++++++----------------- src/qt/bitcoingui.h | 2 -- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 90925b643c..af7b0976eb 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -261,10 +261,6 @@ void BitcoinGUI::createActions() sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2)); tabGroup->addAction(sendCoinsAction); - sendCoinsMenuAction = new QAction(sendCoinsAction->text(), this); - sendCoinsMenuAction->setStatusTip(sendCoinsAction->statusTip()); - sendCoinsMenuAction->setToolTip(sendCoinsMenuAction->statusTip()); - receiveCoinsAction = new QAction(platformStyle->SingleColorIcon(":/icons/receiving_addresses"), tr("&Receive"), this); receiveCoinsAction->setStatusTip(tr("Request payments (generates QR codes and bitcoin: URIs)")); receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip()); @@ -272,10 +268,6 @@ void BitcoinGUI::createActions() receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3)); tabGroup->addAction(receiveCoinsAction); - receiveCoinsMenuAction = new QAction(receiveCoinsAction->text(), this); - receiveCoinsMenuAction->setStatusTip(receiveCoinsAction->statusTip()); - receiveCoinsMenuAction->setToolTip(receiveCoinsMenuAction->statusTip()); - historyAction = new QAction(platformStyle->SingleColorIcon(":/icons/history"), tr("&Transactions"), this); historyAction->setStatusTip(tr("Browse transaction history")); historyAction->setToolTip(historyAction->statusTip()); @@ -290,12 +282,8 @@ void BitcoinGUI::createActions() connect(overviewAction, &QAction::triggered, this, &BitcoinGUI::gotoOverviewPage); connect(sendCoinsAction, &QAction::triggered, [this]{ showNormalIfMinimized(); }); connect(sendCoinsAction, &QAction::triggered, [this]{ gotoSendCoinsPage(); }); - connect(sendCoinsMenuAction, &QAction::triggered, [this]{ showNormalIfMinimized(); }); - connect(sendCoinsMenuAction, &QAction::triggered, [this]{ gotoSendCoinsPage(); }); connect(receiveCoinsAction, &QAction::triggered, [this]{ showNormalIfMinimized(); }); connect(receiveCoinsAction, &QAction::triggered, this, &BitcoinGUI::gotoReceiveCoinsPage); - connect(receiveCoinsMenuAction, &QAction::triggered, [this]{ showNormalIfMinimized(); }); - connect(receiveCoinsMenuAction, &QAction::triggered, this, &BitcoinGUI::gotoReceiveCoinsPage); connect(historyAction, &QAction::triggered, [this]{ showNormalIfMinimized(); }); connect(historyAction, &QAction::triggered, this, &BitcoinGUI::gotoHistoryPage); #endif // ENABLE_WALLET @@ -747,9 +735,7 @@ void BitcoinGUI::setWalletActionsEnabled(bool enabled) { overviewAction->setEnabled(enabled); sendCoinsAction->setEnabled(enabled); - sendCoinsMenuAction->setEnabled(enabled); receiveCoinsAction->setEnabled(enabled); - receiveCoinsMenuAction->setEnabled(enabled); historyAction->setEnabled(enabled); encryptWalletAction->setEnabled(enabled); backupWalletAction->setEnabled(enabled); @@ -790,9 +776,11 @@ void BitcoinGUI::createTrayIconMenu() trayIconMenu->addSeparator(); #endif // Q_OS_MAC + QAction* send_action{nullptr}; + QAction* receive_action{nullptr}; if (enableWallet) { - trayIconMenu->addAction(sendCoinsMenuAction); - trayIconMenu->addAction(receiveCoinsMenuAction); + send_action = trayIconMenu->addAction(sendCoinsAction->text(), sendCoinsAction, &QAction::trigger); + receive_action = trayIconMenu->addAction(receiveCoinsAction->text(), receiveCoinsAction, &QAction::trigger); trayIconMenu->addSeparator(); trayIconMenu->addAction(signMessageAction); trayIconMenu->addAction(verifyMessageAction); @@ -826,11 +814,15 @@ void BitcoinGUI::createTrayIconMenu() // Using QSystemTrayIcon::Context is not reliable. // See https://bugreports.qt.io/browse/QTBUG-91697 trayIconMenu.get(), &QMenu::aboutToShow, - [this, show_hide_action] { + [this, show_hide_action, send_action, receive_action] { if (show_hide_action) show_hide_action->setText( (!isHidden() && !isMinimized() && !GUIUtil::isObscured(this)) ? tr("&Hide") : tr("S&how")); + if (enableWallet) { + send_action->setEnabled(sendCoinsAction->isEnabled()); + receive_action->setEnabled(receiveCoinsAction->isEnabled()); + } }); } diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 887cf3f33d..0ae5f7331e 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -137,7 +137,6 @@ private: QAction* historyAction = nullptr; QAction* quitAction = nullptr; QAction* sendCoinsAction = nullptr; - QAction* sendCoinsMenuAction = nullptr; QAction* usedSendingAddressesAction = nullptr; QAction* usedReceivingAddressesAction = nullptr; QAction* signMessageAction = nullptr; @@ -146,7 +145,6 @@ private: QAction* m_load_psbt_clipboard_action = nullptr; QAction* aboutAction = nullptr; QAction* receiveCoinsAction = nullptr; - QAction* receiveCoinsMenuAction = nullptr; QAction* optionsAction = nullptr; QAction* encryptWalletAction = nullptr; QAction* backupWalletAction = nullptr; From 92427354dd5f80cb5c042e7afbcd386968161be4 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 8 Feb 2022 17:22:10 +0200 Subject: [PATCH 07/11] qt, refactor: Use local QAction instances for the tray icon menu This change is required for the following commit. --- src/qt/bitcoingui.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index af7b0976eb..52764bbf08 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -778,20 +778,24 @@ void BitcoinGUI::createTrayIconMenu() QAction* send_action{nullptr}; QAction* receive_action{nullptr}; + QAction* sign_action{nullptr}; + QAction* verify_action{nullptr}; if (enableWallet) { send_action = trayIconMenu->addAction(sendCoinsAction->text(), sendCoinsAction, &QAction::trigger); receive_action = trayIconMenu->addAction(receiveCoinsAction->text(), receiveCoinsAction, &QAction::trigger); trayIconMenu->addSeparator(); - trayIconMenu->addAction(signMessageAction); - trayIconMenu->addAction(verifyMessageAction); + sign_action = trayIconMenu->addAction(signMessageAction->text(), signMessageAction, &QAction::trigger); + verify_action = trayIconMenu->addAction(verifyMessageAction->text(), verifyMessageAction, &QAction::trigger); trayIconMenu->addSeparator(); } - trayIconMenu->addAction(optionsAction); - trayIconMenu->addAction(openRPCConsoleAction); + QAction* options_action = trayIconMenu->addAction(optionsAction->text(), optionsAction, &QAction::trigger); + options_action->setMenuRole(QAction::PreferencesRole); + QAction* node_window_action = trayIconMenu->addAction(openRPCConsoleAction->text(), openRPCConsoleAction, &QAction::trigger); + QAction* quit_action{nullptr}; #ifndef Q_OS_MAC // Note: On macOS, the Dock icon's menu already has Quit action. trayIconMenu->addSeparator(); - trayIconMenu->addAction(quitAction); + quit_action = trayIconMenu->addAction(quitAction->text(), quitAction, &QAction::trigger); trayIcon->setContextMenu(trayIconMenu.get()); connect(trayIcon, &QSystemTrayIcon::activated, [this](QSystemTrayIcon::ActivationReason reason) { @@ -814,7 +818,7 @@ void BitcoinGUI::createTrayIconMenu() // Using QSystemTrayIcon::Context is not reliable. // See https://bugreports.qt.io/browse/QTBUG-91697 trayIconMenu.get(), &QMenu::aboutToShow, - [this, show_hide_action, send_action, receive_action] { + [this, show_hide_action, send_action, receive_action, sign_action, verify_action] { if (show_hide_action) show_hide_action->setText( (!isHidden() && !isMinimized() && !GUIUtil::isObscured(this)) ? tr("&Hide") : @@ -822,6 +826,8 @@ void BitcoinGUI::createTrayIconMenu() if (enableWallet) { send_action->setEnabled(sendCoinsAction->isEnabled()); receive_action->setEnabled(receiveCoinsAction->isEnabled()); + sign_action->setEnabled(signMessageAction->isEnabled()); + verify_action->setEnabled(verifyMessageAction->isEnabled()); } }); } From 8c0eb80f41bca7b08c94de0f08692fac23e3e9f0 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 8 Feb 2022 17:24:42 +0200 Subject: [PATCH 08/11] qt: Disable tray icon menu when a modal dialog is active --- src/qt/bitcoingui.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 52764bbf08..c34be0ff77 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -818,16 +818,26 @@ void BitcoinGUI::createTrayIconMenu() // Using QSystemTrayIcon::Context is not reliable. // See https://bugreports.qt.io/browse/QTBUG-91697 trayIconMenu.get(), &QMenu::aboutToShow, - [this, show_hide_action, send_action, receive_action, sign_action, verify_action] { + [this, show_hide_action, send_action, receive_action, sign_action, verify_action, options_action, node_window_action, quit_action] { if (show_hide_action) show_hide_action->setText( (!isHidden() && !isMinimized() && !GUIUtil::isObscured(this)) ? tr("&Hide") : tr("S&how")); - if (enableWallet) { - send_action->setEnabled(sendCoinsAction->isEnabled()); - receive_action->setEnabled(receiveCoinsAction->isEnabled()); - sign_action->setEnabled(signMessageAction->isEnabled()); - verify_action->setEnabled(verifyMessageAction->isEnabled()); + if (QApplication::activeModalWidget()) { + for (QAction* a : trayIconMenu.get()->actions()) { + a->setEnabled(false); + } + } else { + if (show_hide_action) show_hide_action->setEnabled(true); + if (enableWallet) { + send_action->setEnabled(sendCoinsAction->isEnabled()); + receive_action->setEnabled(receiveCoinsAction->isEnabled()); + sign_action->setEnabled(signMessageAction->isEnabled()); + verify_action->setEnabled(verifyMessageAction->isEnabled()); + } + options_action->setEnabled(optionsAction->isEnabled()); + node_window_action->setEnabled(openRPCConsoleAction->isEnabled()); + if (quit_action) quit_action->setEnabled(true); } }); } From 89c277a6fca1149f10f8b55874c702c341679765 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 8 Feb 2022 17:25:39 +0200 Subject: [PATCH 09/11] qt: Delay shutdown while a modal dialog is active --- src/qt/bitcoin.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 6a2781079c..eb31287c56 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -268,7 +268,11 @@ void BitcoinApplication::createWindow(const NetworkStyle *networkStyle) connect(window, &BitcoinGUI::quitRequested, this, &BitcoinApplication::requestShutdown); pollShutdownTimer = new QTimer(window); - connect(pollShutdownTimer, &QTimer::timeout, window, &BitcoinGUI::detectShutdown); + connect(pollShutdownTimer, &QTimer::timeout, [this]{ + if (!QApplication::activeModalWidget()) { + window->detectShutdown(); + } + }); } void BitcoinApplication::createSplashScreen(const NetworkStyle *networkStyle) From 5d7666b15164a16aaf3af49af8f73ff4bd392f6a Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 8 Feb 2022 17:26:10 +0200 Subject: [PATCH 10/11] qt: Revert 7fa91e831227e556bd8a7ae3da64bd59d4f30d5f partially The AskPassphraseDialog modal dialog must be synchronous here as expected in the WalletModel::requestUnlock() function. Fixed an introduced regression. --- src/qt/walletview.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 7954a66995..be96e3baa1 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -242,9 +242,11 @@ void WalletView::unlockWallet() { // Unlock wallet when requested by wallet model if (walletModel->getEncryptionStatus() == WalletModel::Locked) { - auto dlg = new AskPassphraseDialog(AskPassphraseDialog::Unlock, this); - dlg->setModel(walletModel); - GUIUtil::ShowModalDialogAndDeleteOnClose(dlg); + AskPassphraseDialog dlg(AskPassphraseDialog::Unlock, this); + dlg.setModel(walletModel); + // A modal dialog must be synchronous here as expected + // in the WalletModel::requestUnlock() function. + dlg.exec(); } } From f730bd7d580502ae3c3b5953ada3724b59f5cd9b Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 8 Feb 2022 18:16:11 +0200 Subject: [PATCH 11/11] scripted-diff: Rename ShowModalDialogAndDeleteOnClose -BEGIN VERIFY SCRIPT- sed -i 's/ShowModalDialogAndDeleteOnClose/ShowModalDialogAsynchronously/' -- $(git grep -l -e "ShowModalDialogAndDeleteOnClose") -END VERIFY SCRIPT- It is important to highlight that a modal dialog is showed asynchronously as there are cases when the synchronous QDialog::exec() is required. --- src/qt/addressbookpage.cpp | 2 +- src/qt/bitcoingui.cpp | 4 ++-- src/qt/guiutil.cpp | 2 +- src/qt/guiutil.h | 2 +- src/qt/sendcoinsdialog.cpp | 2 +- src/qt/transactionview.cpp | 4 ++-- src/qt/walletframe.cpp | 2 +- src/qt/walletview.cpp | 4 ++-- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index a180b03c08..d59a4345f3 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -189,7 +189,7 @@ void AddressBookPage::onEditAction() dlg->setModel(model); QModelIndex origIndex = proxyModel->mapToSource(indexes.at(0)); dlg->loadRow(origIndex.row()); - GUIUtil::ShowModalDialogAndDeleteOnClose(dlg); + GUIUtil::ShowModalDialogAsynchronously(dlg); } void AddressBookPage::on_newAddress_clicked() diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index c34be0ff77..7c22880dd1 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -853,7 +853,7 @@ void BitcoinGUI::aboutClicked() return; auto dlg = new HelpMessageDialog(this, /* about */ true); - GUIUtil::ShowModalDialogAndDeleteOnClose(dlg); + GUIUtil::ShowModalDialogAsynchronously(dlg); } void BitcoinGUI::showDebugWindow() @@ -998,7 +998,7 @@ void BitcoinGUI::openOptionsDialogWithTab(OptionsDialog::Tab tab) connect(dlg, &OptionsDialog::quitOnReset, this, &BitcoinGUI::quitRequested); dlg->setCurrentTab(tab); dlg->setModel(clientModel->getOptionsModel()); - GUIUtil::ShowModalDialogAndDeleteOnClose(dlg); + GUIUtil::ShowModalDialogAsynchronously(dlg); } void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool header, SynchronizationState sync_state) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index dc73bcd911..9565fa508f 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -984,7 +984,7 @@ void PrintSlotException( PrintExceptionContinue(exception, description.c_str()); } -void ShowModalDialogAndDeleteOnClose(QDialog* dialog) +void ShowModalDialogAsynchronously(QDialog* dialog) { dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->setWindowModality(Qt::ApplicationModal); diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 9b25b77325..0224b18b4e 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -426,7 +426,7 @@ namespace GUIUtil /** * Shows a QDialog instance asynchronously, and deletes it on close. */ - void ShowModalDialogAndDeleteOnClose(QDialog* dialog); + void ShowModalDialogAsynchronously(QDialog* dialog); inline bool IsEscapeOrBack(int key) { diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index e37168830e..579ef0c3fd 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -930,7 +930,7 @@ void SendCoinsDialog::coinControlButtonClicked() { auto dlg = new CoinControlDialog(*m_coin_control, model, platformStyle); connect(dlg, &QDialog::finished, this, &SendCoinsDialog::coinControlUpdateLabels); - GUIUtil::ShowModalDialogAndDeleteOnClose(dlg); + GUIUtil::ShowModalDialogAsynchronously(dlg); } // Coin Control: checkbox custom change address diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 1ab1333b72..778ef04b77 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -511,7 +511,7 @@ void TransactionView::editLabel() : EditAddressDialog::EditSendingAddress, this); dlg->setModel(addressBook); dlg->loadRow(idx); - GUIUtil::ShowModalDialogAndDeleteOnClose(dlg); + GUIUtil::ShowModalDialogAsynchronously(dlg); } else { @@ -520,7 +520,7 @@ void TransactionView::editLabel() this); dlg->setModel(addressBook); dlg->setAddress(address); - GUIUtil::ShowModalDialogAndDeleteOnClose(dlg); + GUIUtil::ShowModalDialogAsynchronously(dlg); } } } diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp index 08190f0b9f..91ce420a33 100644 --- a/src/qt/walletframe.cpp +++ b/src/qt/walletframe.cpp @@ -226,7 +226,7 @@ void WalletFrame::gotoLoadPSBT(bool from_clipboard) auto dlg = new PSBTOperationsDialog(this, currentWalletModel(), clientModel); dlg->openWithPSBT(psbtx); - GUIUtil::ShowModalDialogAndDeleteOnClose(dlg); + GUIUtil::ShowModalDialogAsynchronously(dlg); } void WalletFrame::encryptWallet() diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index be96e3baa1..e7ec54721a 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -208,7 +208,7 @@ void WalletView::encryptWallet() auto dlg = new AskPassphraseDialog(AskPassphraseDialog::Encrypt, this); dlg->setModel(walletModel); connect(dlg, &QDialog::finished, this, &WalletView::encryptionStatusChanged); - GUIUtil::ShowModalDialogAndDeleteOnClose(dlg); + GUIUtil::ShowModalDialogAsynchronously(dlg); } void WalletView::backupWallet() @@ -235,7 +235,7 @@ void WalletView::changePassphrase() { auto dlg = new AskPassphraseDialog(AskPassphraseDialog::ChangePass, this); dlg->setModel(walletModel); - GUIUtil::ShowModalDialogAndDeleteOnClose(dlg); + GUIUtil::ShowModalDialogAsynchronously(dlg); } void WalletView::unlockWallet()