Skip to content

Commit 2464925

Browse files
committed
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.
1 parent 53bb6be commit 2464925

File tree

4 files changed

+25
-44
lines changed

4 files changed

+25
-44
lines changed

src/qt/bitcoingui.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,7 @@ void BitcoinGUI::createTrayIcon(const NetworkStyle *networkStyle)
595595
void BitcoinGUI::createTrayIconMenu()
596596
{
597597
#ifndef Q_OS_MAC
598-
// return if trayIcon is unset (only on non-Mac OSes)
598+
// return if trayIcon is unset (only on non-macOSes)
599599
if (!trayIcon)
600600
return;
601601

@@ -604,15 +604,15 @@ void BitcoinGUI::createTrayIconMenu()
604604

605605
connect(trayIcon, &QSystemTrayIcon::activated, this, &BitcoinGUI::trayIconActivated);
606606
#else
607-
// Note: On Mac, the dock icon is used to provide the tray's functionality.
607+
// Note: On macOS, the Dock icon is used to provide the tray's functionality.
608608
MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance();
609-
dockIconHandler->setMainWindow(static_cast<QMainWindow*>(this));
609+
connect(dockIconHandler, &MacDockIconHandler::dockIconClicked, this, &BitcoinGUI::macosDockIconActivated);
610610
trayIconMenu = dockIconHandler->dockMenu();
611611
#endif
612612

613-
// Configuration of the tray icon (or dock icon) icon menu
613+
// Configuration of the tray icon (or Dock icon) menu
614614
#ifndef Q_OS_MAC
615-
// Note: On Mac, the dock icon's menu already has show / hide action.
615+
// Note: On macOS, the Dock icon's menu already has Show / Hide action.
616616
trayIconMenu->addAction(toggleHideAction);
617617
trayIconMenu->addSeparator();
618618
#endif
@@ -626,7 +626,7 @@ void BitcoinGUI::createTrayIconMenu()
626626
trayIconMenu->addAction(openRPCConsoleAction);
627627
}
628628
trayIconMenu->addAction(optionsAction);
629-
#ifndef Q_OS_MAC // This is built-in on Mac
629+
#ifndef Q_OS_MAC // This is built-in on macOS
630630
trayIconMenu->addSeparator();
631631
trayIconMenu->addAction(quitAction);
632632
#endif
@@ -641,6 +641,12 @@ void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
641641
toggleHidden();
642642
}
643643
}
644+
#else
645+
void BitcoinGUI::macosDockIconActivated()
646+
{
647+
show();
648+
activateWindow();
649+
}
644650
#endif
645651

646652
void BitcoinGUI::optionsClicked()

src/qt/bitcoingui.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,9 @@ public Q_SLOTS:
260260
#ifndef Q_OS_MAC
261261
/** Handle tray icon clicked */
262262
void trayIconActivated(QSystemTrayIcon::ActivationReason reason);
263+
#else
264+
/** Handle macOS Dock icon clicked */
265+
void macosDockIconActivated();
263266
#endif
264267

265268
/** Show window if hidden, unminimize when minimized, rise when obscured or show if hidden and fToggleHidden is true */

src/qt/macdockiconhandler.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
1-
// Copyright (c) 2011-2015 The Bitcoin Core developers
1+
// Copyright (c) 2011-2018 The Bitcoin Core developers
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

55
#ifndef BITCOIN_QT_MACDOCKICONHANDLER_H
66
#define BITCOIN_QT_MACDOCKICONHANDLER_H
77

8-
#include <QMainWindow>
98
#include <QObject>
109

1110
QT_BEGIN_NAMESPACE
1211
class QMenu;
1312
class QWidget;
1413
QT_END_NAMESPACE
1514

16-
/** Macintosh-specific dock icon handler.
15+
/** macOS-specific Dock icon handler.
1716
*/
1817
class MacDockIconHandler : public QObject
1918
{
@@ -23,10 +22,8 @@ class MacDockIconHandler : public QObject
2322
~MacDockIconHandler();
2423

2524
QMenu *dockMenu();
26-
void setMainWindow(QMainWindow *window);
2725
static MacDockIconHandler *instance();
2826
static void cleanup();
29-
void handleDockIconClickEvent();
3027

3128
Q_SIGNALS:
3229
void dockIconClicked();
@@ -36,7 +33,6 @@ class MacDockIconHandler : public QObject
3633

3734
QWidget *m_dummyWidget;
3835
QMenu *m_dockMenu;
39-
QMainWindow *mainWindow;
4036
};
4137

4238
#endif // BITCOIN_QT_MACDOCKICONHANDLER_H

src/qt/macdockiconhandler.mm

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2011-2013 The Bitcoin Core developers
1+
// Copyright (c) 2011-2018 The Bitcoin Core developers
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

@@ -18,25 +18,18 @@ bool dockClickHandler(id self,SEL _cmd,...) {
1818
Q_UNUSED(self)
1919
Q_UNUSED(_cmd)
2020

21-
s_instance->handleDockIconClickEvent();
21+
Q_EMIT s_instance->dockIconClicked();
2222

23-
// Return NO (false) to suppress the default OS X actions
23+
// Return NO (false) to suppress the default macOS actions
2424
return false;
2525
}
2626

2727
void setupDockClickHandler() {
28-
Class cls = objc_getClass("NSApplication");
29-
id appInst = objc_msgSend((id)cls, sel_registerName("sharedApplication"));
30-
31-
if (appInst != nullptr) {
32-
id delegate = objc_msgSend(appInst, sel_registerName("delegate"));
33-
Class delClass = (Class)objc_msgSend(delegate, sel_registerName("class"));
34-
SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:");
35-
if (class_getInstanceMethod(delClass, shouldHandle))
36-
class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:");
37-
else
38-
class_addMethod(delClass, shouldHandle, (IMP)dockClickHandler,"B@:");
39-
}
28+
id app = objc_msgSend((id)objc_getClass("NSApplication"), sel_registerName("sharedApplication"));
29+
id delegate = objc_msgSend(app, sel_registerName("delegate"));
30+
Class delClass = (Class)objc_msgSend(delegate, sel_registerName("class"));
31+
SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:");
32+
class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:");
4033
}
4134

4235

@@ -47,21 +40,15 @@ void setupDockClickHandler() {
4740
setupDockClickHandler();
4841
this->m_dummyWidget = new QWidget();
4942
this->m_dockMenu = new QMenu(this->m_dummyWidget);
50-
this->setMainWindow(nullptr);
5143
#if QT_VERSION >= 0x050200
5244
this->m_dockMenu->setAsDockMenu();
5345
#endif
5446
[pool release];
5547
}
5648

57-
void MacDockIconHandler::setMainWindow(QMainWindow *window) {
58-
this->mainWindow = window;
59-
}
60-
6149
MacDockIconHandler::~MacDockIconHandler()
6250
{
6351
delete this->m_dummyWidget;
64-
this->setMainWindow(nullptr);
6552
}
6653

6754
QMenu *MacDockIconHandler::dockMenu()
@@ -80,14 +67,3 @@ void setupDockClickHandler() {
8067
{
8168
delete s_instance;
8269
}
83-
84-
void MacDockIconHandler::handleDockIconClickEvent()
85-
{
86-
if (this->mainWindow)
87-
{
88-
this->mainWindow->activateWindow();
89-
this->mainWindow->show();
90-
}
91-
92-
Q_EMIT this->dockIconClicked();
93-
}

0 commit comments

Comments
 (0)