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