From 33ab678868d4b667fb23dd8b7885e7a836ad2942 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 31 Oct 2018 20:04:05 +0200 Subject: [PATCH 1/7] Remove obj_c for macOS Dock icon setting Qt `setWindowIcon()` does this work. --- src/qt/bitcoingui.cpp | 4 ---- src/qt/macdockiconhandler.h | 2 -- src/qt/macdockiconhandler.mm | 35 ----------------------------------- 3 files changed, 41 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 9145fc673c6bc..7a9bb9a262c70 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -148,12 +148,8 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *_platformStyle, const NetworkStyle * QString userWindowTitle = QString::fromStdString(gArgs.GetArg("-windowtitle", "")); if(!userWindowTitle.isEmpty()) windowTitle += " - " + userWindowTitle; windowTitle += " " + networkStyle->getTitleAddText(); -#ifndef Q_OS_MAC QApplication::setWindowIcon(networkStyle->getTrayAndWindowIcon()); setWindowIcon(networkStyle->getTrayAndWindowIcon()); -#else - MacDockIconHandler::instance()->setIcon(networkStyle->getAppIcon()); -#endif setWindowTitle(windowTitle); #if defined(Q_OS_MAC) && QT_VERSION < 0x050000 diff --git a/src/qt/macdockiconhandler.h b/src/qt/macdockiconhandler.h index 1c28593d4af10..34095ce073866 100644 --- a/src/qt/macdockiconhandler.h +++ b/src/qt/macdockiconhandler.h @@ -9,7 +9,6 @@ #include QT_BEGIN_NAMESPACE -class QIcon; class QMenu; class QWidget; QT_END_NAMESPACE @@ -24,7 +23,6 @@ class MacDockIconHandler : public QObject ~MacDockIconHandler(); QMenu *dockMenu(); - void setIcon(const QIcon &icon); void setMainWindow(QMainWindow *window); static MacDockIconHandler *instance(); static void cleanup(); diff --git a/src/qt/macdockiconhandler.mm b/src/qt/macdockiconhandler.mm index 9e7de0f98fbdf..464df325cad9d 100644 --- a/src/qt/macdockiconhandler.mm +++ b/src/qt/macdockiconhandler.mm @@ -4,9 +4,7 @@ #include "macdockiconhandler.h" -#include #include -#include #include #undef slots @@ -77,39 +75,6 @@ void setupDockClickHandler() { return this->m_dockMenu; } -void MacDockIconHandler::setIcon(const QIcon &icon) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSImage *image = nil; - if (icon.isNull()) - image = [[NSImage imageNamed:@"NSApplicationIcon"] retain]; - else { - // generate NSImage from QIcon and use this as dock icon. - QSize size = icon.actualSize(QSize(128, 128)); - QPixmap pixmap = icon.pixmap(size); - - // Write image into a R/W buffer from raw pixmap, then save the image. - QBuffer notificationBuffer; - if (!pixmap.isNull() && notificationBuffer.open(QIODevice::ReadWrite)) { - QImageWriter writer(¬ificationBuffer, "PNG"); - if (writer.write(pixmap.toImage())) { - NSData* macImgData = [NSData dataWithBytes:notificationBuffer.buffer().data() - length:notificationBuffer.buffer().size()]; - image = [[NSImage alloc] initWithData:macImgData]; - } - } - - if(!image) { - // if testnet image could not be created, load std. app icon - image = [[NSImage imageNamed:@"NSApplicationIcon"] retain]; - } - } - - [NSApp setApplicationIconImage:image]; - [image release]; - [pool release]; -} - MacDockIconHandler *MacDockIconHandler::instance() { if (!s_instance) From 8a6b74c566559fa7653ad8efbff5bbabbfecf1d5 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: [PATCH 2/7] 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. --- src/qt/bitcoingui.cpp | 8 ++++++- src/qt/bitcoingui.h | 3 +++ src/qt/macdockiconhandler.h | 8 ++----- src/qt/macdockiconhandler.mm | 44 ++++++++---------------------------- 4 files changed, 22 insertions(+), 41 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 7a9bb9a262c70..16d903724d740 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -641,7 +641,7 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel) // Note: On Mac, the dock icon is also used to provide menu functionality // similar to one for tray icon MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance(); - dockIconHandler->setMainWindow((QMainWindow *)this); + connect(dockIconHandler, SIGNAL(dockIconClicked()), this, SLOT(macosDockIconActivated())); dockIconMenu = dockIconHandler->dockMenu(); createIconMenu(dockIconMenu); @@ -804,6 +804,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 86811283408f9..8f22bbb40565d 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -274,6 +274,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 34095ce073866..ea77cdf054342 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 @@ class MacDockIconHandler : public QObject ~MacDockIconHandler(); QMenu *dockMenu(); - void setMainWindow(QMainWindow *window); static MacDockIconHandler *instance(); static void cleanup(); - void handleDockIconClickEvent(); Q_SIGNALS: void dockIconClicked(); @@ -36,7 +33,6 @@ class MacDockIconHandler : public QObject 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 464df325cad9d..846603f3ae79e 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. @@ -21,26 +21,19 @@ bool dockClickHandler(id self,SEL _cmd,...) { Q_UNUSED(self) Q_UNUSED(_cmd) - - s_instance->handleDockIconClickEvent(); - - // Return NO (false) to suppress the default OS X actions + + Q_EMIT s_instance->dockIconClicked(); + + // 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@:"); } @@ -51,7 +44,6 @@ void setupDockClickHandler() { setupDockClickHandler(); this->m_dummyWidget = new QWidget(); this->m_dockMenu = new QMenu(this->m_dummyWidget); - this->setMainWindow(nullptr); #if QT_VERSION < 0x050000 qt_mac_set_dock_menu(this->m_dockMenu); #elif QT_VERSION >= 0x050200 @@ -60,14 +52,9 @@ void setupDockClickHandler() { [pool release]; } -void MacDockIconHandler::setMainWindow(QMainWindow *window) { - this->mainWindow = window; -} - MacDockIconHandler::~MacDockIconHandler() { delete this->m_dummyWidget; - this->setMainWindow(nullptr); } QMenu *MacDockIconHandler::dockMenu() @@ -86,14 +73,3 @@ void setupDockClickHandler() { { delete s_instance; } - -void MacDockIconHandler::handleDockIconClickEvent() -{ - if (this->mainWindow) - { - this->mainWindow->activateWindow(); - this->mainWindow->show(); - } - - Q_EMIT this->dockIconClicked(); -} From ee32e3db2ced90f4d52c73b9809e2aac22b8c242 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 2 Nov 2018 10:58:14 +0200 Subject: [PATCH 3/7] Remove obj_c for macOS Dock icon menu Qt `setAsDockMenu()` does this work. --- src/qt/bitcoingui.cpp | 4 +++- src/qt/macdockiconhandler.h | 11 ----------- src/qt/macdockiconhandler.mm | 27 +-------------------------- 3 files changed, 4 insertions(+), 38 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 16d903724d740..8d2076c6f835f 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -642,7 +642,9 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel) // similar to one for tray icon MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance(); connect(dockIconHandler, SIGNAL(dockIconClicked()), this, SLOT(macosDockIconActivated())); - dockIconMenu = dockIconHandler->dockMenu(); + + dockIconMenu = new QMenu(this); + dockIconMenu->setAsDockMenu(); createIconMenu(dockIconMenu); #endif diff --git a/src/qt/macdockiconhandler.h b/src/qt/macdockiconhandler.h index ea77cdf054342..ff867e21a79c0 100644 --- a/src/qt/macdockiconhandler.h +++ b/src/qt/macdockiconhandler.h @@ -7,11 +7,6 @@ #include -QT_BEGIN_NAMESPACE -class QMenu; -class QWidget; -QT_END_NAMESPACE - /** macOS-specific Dock icon handler. */ class MacDockIconHandler : public QObject @@ -19,9 +14,6 @@ class MacDockIconHandler : public QObject Q_OBJECT public: - ~MacDockIconHandler(); - - QMenu *dockMenu(); static MacDockIconHandler *instance(); static void cleanup(); @@ -30,9 +22,6 @@ class MacDockIconHandler : public QObject private: MacDockIconHandler(); - - QWidget *m_dummyWidget; - QMenu *m_dockMenu; }; #endif // BITCOIN_QT_MACDOCKICONHANDLER_H diff --git a/src/qt/macdockiconhandler.mm b/src/qt/macdockiconhandler.mm index 846603f3ae79e..7fcbe106e2fe3 100644 --- a/src/qt/macdockiconhandler.mm +++ b/src/qt/macdockiconhandler.mm @@ -4,11 +4,7 @@ #include "macdockiconhandler.h" -#include -#include - #undef slots -#include #include #include @@ -18,7 +14,7 @@ static MacDockIconHandler *s_instance = nullptr; -bool dockClickHandler(id self,SEL _cmd,...) { +bool dockClickHandler(id self, SEL _cmd, ...) { Q_UNUSED(self) Q_UNUSED(_cmd) @@ -36,30 +32,9 @@ void setupDockClickHandler() { class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:"); } - MacDockIconHandler::MacDockIconHandler() : QObject() { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - setupDockClickHandler(); - this->m_dummyWidget = new QWidget(); - this->m_dockMenu = new QMenu(this->m_dummyWidget); -#if QT_VERSION < 0x050000 - qt_mac_set_dock_menu(this->m_dockMenu); -#elif QT_VERSION >= 0x050200 - this->m_dockMenu->setAsDockMenu(); -#endif - [pool release]; -} - -MacDockIconHandler::~MacDockIconHandler() -{ - delete this->m_dummyWidget; -} - -QMenu *MacDockIconHandler::dockMenu() -{ - return this->m_dockMenu; } MacDockIconHandler *MacDockIconHandler::instance() From 272e77a105f9261ec3c68be27fda18a76fe16b63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Fri, 31 Aug 2018 23:08:07 +0100 Subject: [PATCH 4/7] qt: Add GUIUtil::bringToFront --- src/qt/guiutil.cpp | 32 +++++++++++++++++++++++++++----- src/qt/guiutil.h | 3 +++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index fbdede2948575..cbba2883e1c8f 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -73,6 +73,12 @@ extern double NSAppKitVersionNumber; #if !defined(NSAppKitVersionNumber10_9) #define NSAppKitVersionNumber10_9 1265 #endif + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + +#include +#include #endif namespace GUIUtil { @@ -471,6 +477,27 @@ bool isObscured(QWidget *w) && checkPoint(QPoint(w->width() / 2, w->height() / 2), w)); } +void bringToFront(QWidget* w) +{ +#ifdef Q_OS_MAC + // Force application activation on macOS. With Qt 5.4 this is required when + // an action in the dock menu is triggered. + id app = objc_msgSend((id) objc_getClass("NSApplication"), sel_registerName("sharedApplication")); + objc_msgSend(app, sel_registerName("activateIgnoringOtherApps:"), YES); +#endif + + if (w) { + // activateWindow() (sometimes) helps with keyboard focus on Windows + if (w->isMinimized()) { + w->showNormal(); + } else { + w->show(); + } + w->activateWindow(); + w->raise(); + } +} + void openDebugLogfile() { fs::path pathDebug = GetDataDir() / "debug.log"; @@ -841,13 +868,8 @@ bool SetStartOnSystemStartup(bool fAutoStart) #elif defined(Q_OS_MAC) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // based on: https://github.com/Mozketo/LaunchAtLoginController/blob/master/LaunchAtLoginController.m -#include -#include - LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list, CFURLRef findUrl); LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list, CFURLRef findUrl) { diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 91ec08cca18dd..7dbc18a023c4d 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -151,6 +151,9 @@ namespace GUIUtil // Determine whether a widget is hidden behind other windows bool isObscured(QWidget *w); + // Activate, show and raise the widget + void bringToFront(QWidget* w); + // Open debug.log void openDebugLogfile(); From fe3c3b2f2cc4e9bb53278196f85e5e71f1634249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Fri, 31 Aug 2018 23:16:34 +0100 Subject: [PATCH 5/7] qt: Use GUIUtil::bringToFront where possible --- src/qt/bitcoingui.cpp | 26 +++++--------------------- src/qt/walletview.cpp | 8 ++------ 2 files changed, 7 insertions(+), 27 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 8d2076c6f835f..2b7c5334eada6 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -835,10 +835,7 @@ void BitcoinGUI::aboutClicked() void BitcoinGUI::showDebugWindow() { - rpcConsole->showNormal(); - rpcConsole->show(); - rpcConsole->raise(); - rpcConsole->activateWindow(); + GUIUtil::bringToFront(rpcConsole); } void BitcoinGUI::showInfo() @@ -1472,24 +1469,11 @@ void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden) if(!clientModel) return; - // activateWindow() (sometimes) helps with keyboard focus on Windows - if (isHidden()) - { - show(); - activateWindow(); - } - else if (isMinimized()) - { - showNormal(); - activateWindow(); - } - else if (GUIUtil::isObscured(this)) - { - raise(); - activateWindow(); - } - else if(fToggleHidden) + if (!isHidden() && !isMinimized() && !GUIUtil::isObscured(this) && fToggleHidden) { hide(); + } else { + GUIUtil::bringToFront(this); + } } void BitcoinGUI::toggleHidden() diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 9a29cc9d3221e..ba994914b9a9d 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -346,9 +346,7 @@ void WalletView::usedSendingAddresses() if(!walletModel) return; - usedSendingAddressesPage->show(); - usedSendingAddressesPage->raise(); - usedSendingAddressesPage->activateWindow(); + GUIUtil::bringToFront(usedSendingAddressesPage); } void WalletView::usedReceivingAddresses() @@ -356,9 +354,7 @@ void WalletView::usedReceivingAddresses() if(!walletModel) return; - usedReceivingAddressesPage->show(); - usedReceivingAddressesPage->raise(); - usedReceivingAddressesPage->activateWindow(); + GUIUtil::bringToFront(usedReceivingAddressesPage); } void WalletView::showProgress(const QString &title, int nProgress) From 62bc1f08b1b11fb76a6df2fb7833cd7c80654765 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Fri, 31 Aug 2018 23:23:06 +0100 Subject: [PATCH 6/7] qt: All tray menu actions call showNormalIfMinimized --- src/qt/bitcoingui.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 2b7c5334eada6..c3647600d7c04 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -496,7 +496,9 @@ void BitcoinGUI::createActions() connect(changePassphraseAction, SIGNAL(triggered()), walletFrame, SLOT(changePassphrase())); connect(unlockWalletAction, SIGNAL(triggered()), walletFrame, SLOT(unlockWallet())); connect(lockWalletAction, SIGNAL(triggered()), walletFrame, SLOT(lockWallet())); + connect(signMessageAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); connect(signMessageAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab())); + connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(gotoVerifyMessageTab())); connect(usedSendingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedSendingAddresses())); connect(usedReceivingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedReceivingAddresses())); From 01e629a9512096f9b419400ceb8f3357f1398e7f Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sun, 25 Aug 2019 13:13:39 +0300 Subject: [PATCH 7/7] qt: Replace objc_msgSend with native syntax --- configure.ac | 2 +- src/qt/guiutil.cpp | 9 ++++----- src/qt/macdockiconhandler.mm | 21 ++++++++++++++------- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/configure.ac b/configure.ac index c200030065e80..eeadd1348b881 100644 --- a/configure.ac +++ b/configure.ac @@ -539,7 +539,7 @@ case $host in fi AX_CHECK_LINK_FLAG([[-Wl,-headerpad_max_install_names]], [LDFLAGS="$LDFLAGS -Wl,-headerpad_max_install_names"]) - CPPFLAGS="$CPPFLAGS -DMAC_OSX" + CPPFLAGS="$CPPFLAGS -DMAC_OSX -DOBJC_OLD_DISPATCH_PROTOTYPES=0" OBJCXXFLAGS="$CXXFLAGS" ;; *linux*) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index cbba2883e1c8f..e0453db646acb 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -77,8 +77,10 @@ extern double NSAppKitVersionNumber; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#include #include +#include + +void ForceActivation(); #endif namespace GUIUtil { @@ -480,10 +482,7 @@ bool isObscured(QWidget *w) void bringToFront(QWidget* w) { #ifdef Q_OS_MAC - // Force application activation on macOS. With Qt 5.4 this is required when - // an action in the dock menu is triggered. - id app = objc_msgSend((id) objc_getClass("NSApplication"), sel_registerName("sharedApplication")); - objc_msgSend(app, sel_registerName("activateIgnoringOtherApps:"), YES); + ForceActivation(); #endif if (w) { diff --git a/src/qt/macdockiconhandler.mm b/src/qt/macdockiconhandler.mm index 7fcbe106e2fe3..e246535c0ec3b 100644 --- a/src/qt/macdockiconhandler.mm +++ b/src/qt/macdockiconhandler.mm @@ -1,12 +1,11 @@ -// Copyright (c) 2011-2018 The Bitcoin Core developers +// Copyright (c) 2011-2019 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "macdockiconhandler.h" -#undef slots -#include -#include +#include +#include #if QT_VERSION < 0x050000 extern void qt_mac_set_dock_menu(QMenu *); @@ -25,9 +24,7 @@ bool dockClickHandler(id self, SEL _cmd, ...) { } void setupDockClickHandler() { - 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")); + Class delClass = (Class)[[[NSApplication sharedApplication] delegate] class]; SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:"); class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:"); } @@ -48,3 +45,13 @@ void setupDockClickHandler() { { delete s_instance; } + +/** + * Force application activation on macOS. With Qt 5.5.1 this is required when + * an action in the Dock menu is triggered. + * TODO: Define a Qt version where it's no-longer necessary. + */ +void ForceActivation() +{ + [[NSApplication sharedApplication] activateIgnoringOtherApps:YES]; +}