Raven Core  3.0.0
P2P Digital Currency
macdockiconhandler.mm
Go to the documentation of this file.
1 // Copyright (c) 2011-2013 The Bitcoin Core developers
2 // Copyright (c) 2017-2019 The Raven Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include "macdockiconhandler.h"
7 
8 #include <QImageWriter>
9 #include <QMenu>
10 #include <QBuffer>
11 #include <QWidget>
12 
13 #undef slots
14 #include <Cocoa/Cocoa.h>
15 #include <objc/objc.h>
16 #include <objc/message.h>
17 
18 #if QT_VERSION < 0x050000
19 extern void qt_mac_set_dock_menu(QMenu *);
20 #endif
21 
22 static MacDockIconHandler *s_instance = nullptr;
23 
24 bool dockClickHandler(id self,SEL _cmd,...) {
25  Q_UNUSED(self)
26  Q_UNUSED(_cmd)
27 
28  s_instance->handleDockIconClickEvent();
29 
30  // Return NO (false) to suppress the default OS X actions
31  return false;
32 }
33 
35  Class cls = objc_getClass("NSApplication");
36  id appInst = objc_msgSend((id)cls, sel_registerName("sharedApplication"));
37 
38  if (appInst != nullptr) {
39  id delegate = objc_msgSend(appInst, sel_registerName("delegate"));
40  Class delClass = (Class)objc_msgSend(delegate, sel_registerName("class"));
41  SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:");
42  if (class_getInstanceMethod(delClass, shouldHandle))
43  class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:");
44  else
45  class_addMethod(delClass, shouldHandle, (IMP)dockClickHandler,"B@:");
46  }
47 }
48 
49 
51 {
52  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
53 
55  this->m_dummyWidget = new QWidget();
56  this->m_dockMenu = new QMenu(this->m_dummyWidget);
57  this->setMainWindow(nullptr);
58 #if QT_VERSION < 0x050000
60 #elif QT_VERSION >= 0x050200
61  this->m_dockMenu->setAsDockMenu();
62 #endif
63  [pool release];
64 }
65 
66 void MacDockIconHandler::setMainWindow(QMainWindow *window) {
67  this->mainWindow = window;
68 }
69 
71 {
72  delete this->m_dummyWidget;
73  this->setMainWindow(nullptr);
74 }
75 
77 {
78  return this->m_dockMenu;
79 }
80 
81 void MacDockIconHandler::setIcon(const QIcon &icon)
82 {
83  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
84  NSImage *image = nil;
85  if (icon.isNull())
86  image = [[NSImage imageNamed:@"NSApplicationIcon"] retain];
87  else {
88  // generate NSImage from QIcon and use this as dock icon.
89  QSize size = icon.actualSize(QSize(128, 128));
90  QPixmap pixmap = icon.pixmap(size);
91 
92  // Write image into a R/W buffer from raw pixmap, then save the image.
93  QBuffer notificationBuffer;
94  if (!pixmap.isNull() && notificationBuffer.open(QIODevice::ReadWrite)) {
95  QImageWriter writer(&notificationBuffer, "PNG");
96  if (writer.write(pixmap.toImage())) {
97  NSData* macImgData = [NSData dataWithBytes:notificationBuffer.buffer().data()
98  length:notificationBuffer.buffer().size()];
99  image = [[NSImage alloc] initWithData:macImgData];
100  }
101  }
102 
103  if(!image) {
104  // if testnet image could not be created, load std. app icon
105  image = [[NSImage imageNamed:@"NSApplicationIcon"] retain];
106  }
107  }
108 
109  [NSApp setApplicationIconImage:image];
110  [image release];
111  [pool release];
112 }
113 
115 {
116  if (!s_instance)
117  s_instance = new MacDockIconHandler();
118  return s_instance;
119 }
120 
122 {
123  delete s_instance;
124 }
125 
127 {
128  if (this->mainWindow)
129  {
130  this->mainWindow->activateWindow();
131  this->mainWindow->show();
132  }
133 
134  Q_EMIT this->dockIconClicked();
135 }
QMainWindow * mainWindow
void setupDockClickHandler()
void qt_mac_set_dock_menu(QMenu *)
Macintosh-specific dock icon handler.
void setIcon(const QIcon &icon)
static MacDockIconHandler * instance()
void setMainWindow(QMainWindow *window)
bool dockClickHandler(id self, SEL _cmd,...)