Changeset View
Changeset View
Standalone View
Standalone View
src/qt/macdockiconhandler.mm
// 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 | // 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. | ||||
#include "macdockiconhandler.h" | #include "macdockiconhandler.h" | ||||
#undef slots | #include <AppKit/AppKit.h> | ||||
#include <objc/message.h> | #include <objc/runtime.h> | ||||
#include <objc/objc.h> | |||||
static MacDockIconHandler *s_instance = nullptr; | static MacDockIconHandler *s_instance = nullptr; | ||||
bool dockClickHandler(id self, SEL _cmd, ...) { | bool dockClickHandler(id self, SEL _cmd, ...) { | ||||
Q_UNUSED(self) | Q_UNUSED(self) | ||||
Q_UNUSED(_cmd) | Q_UNUSED(_cmd) | ||||
Q_EMIT s_instance->dockIconClicked(); | Q_EMIT s_instance->dockIconClicked(); | ||||
// Return NO (false) to suppress the default macOS actions | // Return NO (false) to suppress the default macOS actions | ||||
return false; | return false; | ||||
} | } | ||||
void setupDockClickHandler() { | void setupDockClickHandler() { | ||||
id app = objc_msgSend((id)objc_getClass("NSApplication"), | Class delClass = | ||||
sel_registerName("sharedApplication")); | (Class)[[[NSApplication sharedApplication] delegate] class]; | ||||
id delegate = objc_msgSend(app, sel_registerName("delegate")); | |||||
Class delClass = (Class)objc_msgSend(delegate, sel_registerName("class")); | |||||
SEL shouldHandle = | SEL shouldHandle = | ||||
sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:"); | sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:"); | ||||
class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:"); | class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:"); | ||||
} | } | ||||
MacDockIconHandler::MacDockIconHandler() : QObject() { | MacDockIconHandler::MacDockIconHandler() : QObject() { | ||||
setupDockClickHandler(); | setupDockClickHandler(); | ||||
} | } | ||||
MacDockIconHandler *MacDockIconHandler::instance() { | MacDockIconHandler *MacDockIconHandler::instance() { | ||||
if (!s_instance) s_instance = new MacDockIconHandler(); | if (!s_instance) s_instance = new MacDockIconHandler(); | ||||
return s_instance; | return s_instance; | ||||
} | } | ||||
void MacDockIconHandler::cleanup() { | void MacDockIconHandler::cleanup() { | ||||
delete s_instance; | 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]; | |||||
} |