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: 2464925e7b
This commit is contained in:
parent
4d4bc37df9
commit
90347141bd
4 changed files with 25 additions and 44 deletions
|
@ -585,7 +585,7 @@ void BitcoinGUI::createTrayIcon(const NetworkStyle *networkStyle)
|
||||||
void BitcoinGUI::createTrayIconMenu()
|
void BitcoinGUI::createTrayIconMenu()
|
||||||
{
|
{
|
||||||
#ifndef Q_OS_MAC
|
#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)
|
if (!trayIcon)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -595,15 +595,15 @@ void BitcoinGUI::createTrayIconMenu()
|
||||||
connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
|
connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
|
||||||
this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason)));
|
this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason)));
|
||||||
#else
|
#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();
|
MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance();
|
||||||
dockIconHandler->setMainWindow(static_cast<QMainWindow*>(this));
|
connect(dockIconHandler, &MacDockIconHandler::dockIconClicked, this, &BitcoinGUI::macosDockIconActivated);
|
||||||
trayIconMenu = dockIconHandler->dockMenu();
|
trayIconMenu = dockIconHandler->dockMenu();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Configuration of the tray icon (or dock icon) icon menu
|
// Configuration of the tray icon (or Dock icon) menu
|
||||||
#ifndef Q_OS_MAC
|
#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->addAction(toggleHideAction);
|
||||||
trayIconMenu->addSeparator();
|
trayIconMenu->addSeparator();
|
||||||
#endif
|
#endif
|
||||||
|
@ -617,7 +617,7 @@ void BitcoinGUI::createTrayIconMenu()
|
||||||
trayIconMenu->addAction(openRPCConsoleAction);
|
trayIconMenu->addAction(openRPCConsoleAction);
|
||||||
}
|
}
|
||||||
trayIconMenu->addAction(optionsAction);
|
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->addSeparator();
|
||||||
trayIconMenu->addAction(quitAction);
|
trayIconMenu->addAction(quitAction);
|
||||||
#endif
|
#endif
|
||||||
|
@ -632,6 +632,12 @@ void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
|
||||||
toggleHidden();
|
toggleHidden();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
void BitcoinGUI::macosDockIconActivated()
|
||||||
|
{
|
||||||
|
show();
|
||||||
|
activateWindow();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void BitcoinGUI::optionsClicked()
|
void BitcoinGUI::optionsClicked()
|
||||||
|
|
|
@ -250,6 +250,9 @@ private Q_SLOTS:
|
||||||
#ifndef Q_OS_MAC
|
#ifndef Q_OS_MAC
|
||||||
/** Handle tray icon clicked */
|
/** Handle tray icon clicked */
|
||||||
void trayIconActivated(QSystemTrayIcon::ActivationReason reason);
|
void trayIconActivated(QSystemTrayIcon::ActivationReason reason);
|
||||||
|
#else
|
||||||
|
/** Handle macOS Dock icon clicked */
|
||||||
|
void macosDockIconActivated();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Show window if hidden, unminimize when minimized, rise when obscured or show if hidden and fToggleHidden is true */
|
/** Show window if hidden, unminimize when minimized, rise when obscured or show if hidden and fToggleHidden is true */
|
||||||
|
|
|
@ -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
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#ifndef BITCOIN_QT_MACDOCKICONHANDLER_H
|
#ifndef BITCOIN_QT_MACDOCKICONHANDLER_H
|
||||||
#define BITCOIN_QT_MACDOCKICONHANDLER_H
|
#define BITCOIN_QT_MACDOCKICONHANDLER_H
|
||||||
|
|
||||||
#include <QMainWindow>
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
@ -13,7 +12,7 @@ class QMenu;
|
||||||
class QWidget;
|
class QWidget;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
/** Macintosh-specific dock icon handler.
|
/** macOS-specific Dock icon handler.
|
||||||
*/
|
*/
|
||||||
class MacDockIconHandler : public QObject
|
class MacDockIconHandler : public QObject
|
||||||
{
|
{
|
||||||
|
@ -23,10 +22,8 @@ public:
|
||||||
~MacDockIconHandler();
|
~MacDockIconHandler();
|
||||||
|
|
||||||
QMenu *dockMenu();
|
QMenu *dockMenu();
|
||||||
void setMainWindow(QMainWindow *window);
|
|
||||||
static MacDockIconHandler *instance();
|
static MacDockIconHandler *instance();
|
||||||
static void cleanup();
|
static void cleanup();
|
||||||
void handleDockIconClickEvent();
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void dockIconClicked();
|
void dockIconClicked();
|
||||||
|
@ -36,7 +33,6 @@ private:
|
||||||
|
|
||||||
QWidget *m_dummyWidget;
|
QWidget *m_dummyWidget;
|
||||||
QMenu *m_dockMenu;
|
QMenu *m_dockMenu;
|
||||||
QMainWindow *mainWindow;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BITCOIN_QT_MACDOCKICONHANDLER_H
|
#endif // BITCOIN_QT_MACDOCKICONHANDLER_H
|
||||||
|
|
|
@ -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
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// 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(self)
|
||||||
Q_UNUSED(_cmd)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupDockClickHandler() {
|
void setupDockClickHandler() {
|
||||||
Class cls = objc_getClass("NSApplication");
|
id app = objc_msgSend((id)objc_getClass("NSApplication"), sel_registerName("sharedApplication"));
|
||||||
id appInst = objc_msgSend((id)cls, sel_registerName("sharedApplication"));
|
id delegate = objc_msgSend(app, sel_registerName("delegate"));
|
||||||
|
Class delClass = (Class)objc_msgSend(delegate, sel_registerName("class"));
|
||||||
if (appInst != nullptr) {
|
SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:");
|
||||||
id delegate = objc_msgSend(appInst, sel_registerName("delegate"));
|
class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:");
|
||||||
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@:");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,21 +40,15 @@ MacDockIconHandler::MacDockIconHandler() : QObject()
|
||||||
setupDockClickHandler();
|
setupDockClickHandler();
|
||||||
this->m_dummyWidget = new QWidget();
|
this->m_dummyWidget = new QWidget();
|
||||||
this->m_dockMenu = new QMenu(this->m_dummyWidget);
|
this->m_dockMenu = new QMenu(this->m_dummyWidget);
|
||||||
this->setMainWindow(nullptr);
|
|
||||||
#if QT_VERSION >= 0x050200
|
#if QT_VERSION >= 0x050200
|
||||||
this->m_dockMenu->setAsDockMenu();
|
this->m_dockMenu->setAsDockMenu();
|
||||||
#endif
|
#endif
|
||||||
[pool release];
|
[pool release];
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacDockIconHandler::setMainWindow(QMainWindow *window) {
|
|
||||||
this->mainWindow = window;
|
|
||||||
}
|
|
||||||
|
|
||||||
MacDockIconHandler::~MacDockIconHandler()
|
MacDockIconHandler::~MacDockIconHandler()
|
||||||
{
|
{
|
||||||
delete this->m_dummyWidget;
|
delete this->m_dummyWidget;
|
||||||
this->setMainWindow(nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QMenu *MacDockIconHandler::dockMenu()
|
QMenu *MacDockIconHandler::dockMenu()
|
||||||
|
@ -80,14 +67,3 @@ void MacDockIconHandler::cleanup()
|
||||||
{
|
{
|
||||||
delete s_instance;
|
delete s_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacDockIconHandler::handleDockIconClickEvent()
|
|
||||||
{
|
|
||||||
if (this->mainWindow)
|
|
||||||
{
|
|
||||||
this->mainWindow->activateWindow();
|
|
||||||
this->mainWindow->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_EMIT this->dockIconClicked();
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue