Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qcocoaapplication.mm
Go to the documentation of this file.
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// Copyright (c) 2007-2008, Apple, Inc.
3
// SPDX-License-Identifier: BSD-3-Clause
4
// Qt-Security score:significant reason:default
5
6
#
include
<
AppKit
/
AppKit
.
h
>
7
8
#
include
"qcocoaapplication.h"
9
10
#
include
"qcocoaintrospection.h"
11
#
include
"qcocoaapplicationdelegate.h"
12
#
include
"qcocoahelpers.h"
13
#
include
"qcocoawindow.h"
14
#
include
<
qguiapplication
.
h
>
15
#
include
<
qdebug
.
h
>
16
17
QT_USE_NAMESPACE
18
19
static
void
qt_sendPostedMessage
(NSEvent *event)
20
{
21
// WARNING: data1 and data2 is truncated to from 64-bit to 32-bit on OS 10.5!
22
// That is why we need to split the address in two parts:
23
quint64 lower = [event data1];
24
quint64 upper = [event data2];
25
QCocoaPostMessageArgs *args =
reinterpret_cast
<QCocoaPostMessageArgs *>(lower | (upper << 32));
26
// Special case for convenience: if the argument is an NSNumber, we unbox it directly.
27
// Use NSValue instead if this behaviour is unwanted.
28
id a1 = ([args->arg1 isKindOfClass:[NSNumber
class
]]) ? (id)[args->arg1 longValue] : args->arg1;
29
id a2 = ([args->arg2 isKindOfClass:[NSNumber
class
]]) ? (id)[args->arg2 longValue] : args->arg2;
30
switch
(args->argCount) {
31
case
0:
32
[args->target performSelector:args->selector];
33
break
;
34
case
1:
35
[args->target performSelector:args->selector withObject:a1];
36
break
;
37
case
3:
38
[args->target performSelector:args->selector withObject:a1 withObject:a2];
39
break
;
40
}
41
42
delete
args;
43
}
44
45
static
const
QByteArray
q_macLocalEventType
= QByteArrayLiteral(
"mac_generic_NSEvent"
);
46
47
static
bool
qt_filterEvent
(NSEvent *event)
48
{
49
if
(
qApp
&&
qApp
->eventDispatcher()->
50
filterNativeEvent(q_macLocalEventType,
static_cast
<
void
*>(event),
nullptr
))
51
return
true
;
52
53
if
(event.type == NSEventTypeApplicationDefined) {
54
switch
(
static_cast
<
short
>(event.subtype)) {
55
case
QtCocoaEventSubTypePostMessage:
56
qt_sendPostedMessage(event);
57
return
true
;
58
default
:
59
break
;
60
}
61
}
62
63
return
false
;
64
}
65
66
static
void
qt_maybeSendKeyEquivalentUpEvent
(NSEvent *event)
67
{
68
// Cocoa is known for not sending key up events for key
69
// equivalents, regardless of whether it's an actual
70
// recognized key equivalent. We decide to force fate
71
// and forward the key event to the key (focus) window.
72
// However, non-Qt windows will not (and should not) get
73
// any special treatment, only QWindow-owned NSWindows.
74
if
(event.type == NSEventTypeKeyUp && (event.modifierFlags & NSEventModifierFlagCommand)) {
75
NSWindow *targetWindow = event.window;
76
if
([targetWindow.
class
conformsToProtocol:@protocol(QNSWindowProtocol)])
77
[targetWindow sendEvent:event];
78
}
79
}
80
81
@implementation QNSApplication
82
83
- (
void
)QT_MANGLE_NAMESPACE(qt_sendEvent_original):(NSEvent *)event
84
{
85
Q_UNUSED(event);
86
// This method will only be used as a signature
87
// template for the method we add into NSApplication
88
// containing the original [NSApplication sendEvent:] implementation
89
}
90
91
- (
void
)QT_MANGLE_NAMESPACE(qt_sendEvent_replacement):(NSEvent *)event
92
{
93
// This method (or its implementation to be precise) will
94
// be called instead of sendEvent if redirection occurs.
95
// 'self' will then be an instance of NSApplication
96
// (and not QNSApplication)
97
if
(!qt_filterEvent(event)) {
98
[self QT_MANGLE_NAMESPACE(qt_sendEvent_original):event];
99
qt_maybeSendKeyEquivalentUpEvent(event);
100
}
101
}
102
103
- (
void
)sendEvent:(NSEvent *)event
104
{
105
// This method will be called if
106
// no redirection occurs
107
if
(!qt_filterEvent(event)) {
108
[super sendEvent:event];
109
qt_maybeSendKeyEquivalentUpEvent(event);
110
}
111
}
112
113
@end
114
115
QT_BEGIN_NAMESPACE
116
117
void
qt_redirectNSApplicationSendEvent()
118
{
119
if
(QCoreApplication::testAttribute(Qt::AA_PluginApplication))
120
// In a plugin we cannot chain sendEvent hooks: a second plugin could
121
// store the implementation of the first, which during the program flow
122
// can be unloaded.
123
return
;
124
125
if
([NSApp isMemberOfClass:[QNSApplication
class
]]) {
126
// No need to change implementation since Qt
127
// already controls a subclass of NSApplication
128
return
;
129
}
130
131
// Change the implementation of [NSApplication sendEvent] to the
132
// implementation of qt_sendEvent_replacement found in QNSApplication.
133
// And keep the old implementation that gets overwritten inside a new
134
// method 'qt_sendEvent_original' that we add to NSApplication
135
qt_cocoa_change_implementation(
136
[NSApplication
class
],
137
@selector(sendEvent:),
138
[QNSApplication
class
],
139
@selector(QT_MANGLE_NAMESPACE(qt_sendEvent_replacement):),
140
@selector(QT_MANGLE_NAMESPACE(qt_sendEvent_original):));
141
}
142
143
void
qt_resetNSApplicationSendEvent
()
144
{
145
if
(QCoreApplication::testAttribute(Qt::AA_PluginApplication))
146
return
;
147
148
149
qt_cocoa_change_back_implementation([NSApplication
class
],
150
@selector(sendEvent:),
151
@selector(QT_MANGLE_NAMESPACE(qt_sendEvent_original):));
152
}
153
154
QT_END_NAMESPACE
qt_filterEvent
static bool qt_filterEvent(NSEvent *event)
Definition
qcocoaapplication.mm:47
qt_sendPostedMessage
static QT_USE_NAMESPACE void qt_sendPostedMessage(NSEvent *event)
Definition
qcocoaapplication.mm:19
q_macLocalEventType
static const QByteArray q_macLocalEventType
Definition
qcocoaapplication.mm:45
qt_maybeSendKeyEquivalentUpEvent
static void qt_maybeSendKeyEquivalentUpEvent(NSEvent *event)
Definition
qcocoaapplication.mm:66
qt_resetNSApplicationSendEvent
void qt_resetNSApplicationSendEvent()
Definition
qcocoaapplication.mm:143
qApp
#define qApp
Definition
qcoreapplication.h:38
qtbase
src
plugins
platforms
cocoa
qcocoaapplication.mm
Generated on
for Qt by
1.18.0