From 90347141bdb4020875c55ff51375aada46a1a4d9 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 31 Oct 2018 21:15:31 +0200 Subject: Use Qt signal for macOS Dock icon click event This moves the Dock icon click reaction code to the common place and allows some cleanup in obj_c code. According to the Apple's docs `class_replaceMethod` behaves as `class_addMethod`, if the method identified by name does not yet exist; or as `method_setImplementation`, if it does exist. Github-Pull: #14597 Rebased-From: 2464925e7be832d4926b6204169bbbc1646c6368 --- src/qt/bitcoingui.cpp | 18 ++++++++++++------ src/qt/bitcoingui.h | 3 +++ src/qt/macdockiconhandler.h | 8 ++------ src/qt/macdockiconhandler.mm | 40 ++++++++-------------------------------- 4 files changed, 25 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 4a9cb58d1d..a8b9aef9ad 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -585,7 +585,7 @@ void BitcoinGUI::createTrayIcon(const NetworkStyle *networkStyle) void BitcoinGUI::createTrayIconMenu() { #ifndef Q_OS_MAC - // return if trayIcon is unset (only on non-Mac OSes) + // return if trayIcon is unset (only on non-macOSes) if (!trayIcon) return; @@ -595,15 +595,15 @@ void BitcoinGUI::createTrayIconMenu() connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason))); #else - // Note: On Mac, the dock icon is used to provide the tray's functionality. + // Note: On macOS, the Dock icon is used to provide the tray's functionality. MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance(); - dockIconHandler->setMainWindow(static_cast(this)); + connect(dockIconHandler, &MacDockIconHandler::dockIconClicked, this, &BitcoinGUI::macosDockIconActivated); trayIconMenu = dockIconHandler->dockMenu(); #endif - // Configuration of the tray icon (or dock icon) icon menu + // Configuration of the tray icon (or Dock icon) menu #ifndef Q_OS_MAC - // Note: On Mac, the dock icon's menu already has show / hide action. + // Note: On macOS, the Dock icon's menu already has Show / Hide action. trayIconMenu->addAction(toggleHideAction); trayIconMenu->addSeparator(); #endif @@ -617,7 +617,7 @@ void BitcoinGUI::createTrayIconMenu() trayIconMenu->addAction(openRPCConsoleAction); } trayIconMenu->addAction(optionsAction); -#ifndef Q_OS_MAC // This is built-in on Mac +#ifndef Q_OS_MAC // This is built-in on macOS trayIconMenu->addSeparator(); trayIconMenu->addAction(quitAction); #endif @@ -632,6 +632,12 @@ 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 c14265cc9c..f4b1bf18ee 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -250,6 +250,9 @@ private 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 */ diff --git a/src/qt/macdockiconhandler.h b/src/qt/macdockiconhandler.h index 34095ce073..ea77cdf054 100644 --- a/src/qt/macdockiconhandler.h +++ b/src/qt/macdockiconhandler.h @@ -1,11 +1,10 @@ -// Copyright (c) 2011-2015 The Bitcoin Core developers +// Copyright (c) 2011-2018 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_MACDOCKICONHANDLER_H #define BITCOIN_QT_MACDOCKICONHANDLER_H -#include #include QT_BEGIN_NAMESPACE @@ -13,7 +12,7 @@ class QMenu; class QWidget; QT_END_NAMESPACE -/** Macintosh-specific dock icon handler. +/** macOS-specific Dock icon handler. */ class MacDockIconHandler : public QObject { @@ -23,10 +22,8 @@ public: ~MacDockIconHandler(); QMenu *dockMenu(); - void setMainWindow(QMainWindow *window); static MacDockIconHandler *instance(); static void cleanup(); - void handleDockIconClickEvent(); Q_SIGNALS: void dockIconClicked(); @@ -36,7 +33,6 @@ private: QWidget *m_dummyWidget; QMenu *m_dockMenu; - QMainWindow *mainWindow; }; #endif // BITCOIN_QT_MACDOCKICONHANDLER_H diff --git a/src/qt/macdockiconhandler.mm b/src/qt/macdockiconhandler.mm index 7c174be617..a356617697 100644 --- a/src/qt/macdockiconhandler.mm +++ b/src/qt/macdockiconhandler.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2018 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -18,25 +18,18 @@ bool dockClickHandler(id self,SEL _cmd,...) { Q_UNUSED(self) Q_UNUSED(_cmd) - s_instance->handleDockIconClickEvent(); + Q_EMIT s_instance->dockIconClicked(); - // Return NO (false) to suppress the default OS X actions + // Return NO (false) to suppress the default macOS actions return false; } void setupDockClickHandler() { - Class cls = objc_getClass("NSApplication"); - id appInst = objc_msgSend((id)cls, sel_registerName("sharedApplication")); - - if (appInst != nullptr) { - id delegate = objc_msgSend(appInst, sel_registerName("delegate")); - Class delClass = (Class)objc_msgSend(delegate, sel_registerName("class")); - SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:"); - if (class_getInstanceMethod(delClass, shouldHandle)) - class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:"); - else - class_addMethod(delClass, shouldHandle, (IMP)dockClickHandler,"B@:"); - } + id app = objc_msgSend((id)objc_getClass("NSApplication"), sel_registerName("sharedApplication")); + id delegate = objc_msgSend(app, sel_registerName("delegate")); + Class delClass = (Class)objc_msgSend(delegate, sel_registerName("class")); + SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:"); + class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:"); } @@ -47,21 +40,15 @@ MacDockIconHandler::MacDockIconHandler() : QObject() setupDockClickHandler(); this->m_dummyWidget = new QWidget(); this->m_dockMenu = new QMenu(this->m_dummyWidget); - this->setMainWindow(nullptr); #if QT_VERSION >= 0x050200 this->m_dockMenu->setAsDockMenu(); #endif [pool release]; } -void MacDockIconHandler::setMainWindow(QMainWindow *window) { - this->mainWindow = window; -} - MacDockIconHandler::~MacDockIconHandler() { delete this->m_dummyWidget; - this->setMainWindow(nullptr); } QMenu *MacDockIconHandler::dockMenu() @@ -80,14 +67,3 @@ void MacDockIconHandler::cleanup() { delete s_instance; } - -void MacDockIconHandler::handleDockIconClickEvent() -{ - if (this->mainWindow) - { - this->mainWindow->activateWindow(); - this->mainWindow->show(); - } - - Q_EMIT this->dockIconClicked(); -} -- cgit v1.2.3