Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qcocoahelpers.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QCOCOAHELPERS_H
5#define QCOCOAHELPERS_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It provides helper functions
12// for the Cocoa plugin. This header file may
13// change from version to version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <private/qguiapplication_p.h>
19#include <QtCore/qloggingcategory.h>
20#include <QtGui/qpalette.h>
21#include <QtGui/qscreen.h>
22#include <qpa/qplatformdialoghelper.h>
23
24#include <objc/runtime.h>
25#include <objc/message.h>
26
27#if defined(__OBJC__)
28
30
31struct mach_header;
32
34
39Q_DECLARE_LOGGING_CATEGORY(lcQpaInputMethods)
41Q_DECLARE_LOGGING_CATEGORY(lcQpaApplication)
42Q_DECLARE_LOGGING_CATEGORY(lcQpaClipboard)
43Q_DECLARE_LOGGING_CATEGORY(lcInputDevices)
46
47class QPixmap;
48class QString;
49
50// Conversion functions
51QStringList qt_mac_NSArrayToQStringList(NSArray<NSString *> *nsarray);
52NSMutableArray<NSString *> *qt_mac_QStringListToNSMutableArray(const QStringList &list);
53
54NSDragOperation qt_mac_mapDropAction(Qt::DropAction action);
55NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions);
56Qt::DropAction qt_mac_mapNSDragOperation(NSDragOperation nsActions);
57Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions);
58
60
61// Misc
64
67
70
72
73Qt::MouseButtons cocoaMouseButtons2QtMouseButtons(NSInteger pressedMouseButtons);
74Qt::MouseButtons currentlyPressedMouseButtons();
75
76// strip out '&' characters, and convert "&&" to a single '&', in menu
77// text - since menu text is sometimes decorated with these for Windows
78// accelerators.
80
81// Similar to __NXKitString for localized AppKit strings
82NSString *qt_mac_AppKitString(NSString *table, NSString *key);
83
84enum {
85 QtCocoaEventSubTypeWakeup = SHRT_MAX,
86 QtCocoaEventSubTypePostMessage = SHRT_MAX-1
87};
88
89class QCocoaPostMessageArgs {
90public:
91 id target;
92 SEL selector;
93 int argCount;
94 id arg1;
95 id arg2;
96 QCocoaPostMessageArgs(id target, SEL selector, int argCount=0, id arg1=0, id arg2=0)
97 : target(target), selector(selector), argCount(argCount), arg1(arg1), arg2(arg2)
98 {
99 [target retain];
100 [arg1 retain];
101 [arg2 retain];
102 }
103
104 ~QCocoaPostMessageArgs()
105 {
106 [arg2 release];
107 [arg1 release];
108 [target release];
109 }
110};
111
112template<typename T>
113T qt_mac_resolveOption(const T &fallback, const QByteArray &environment)
114{
115 // check for environment variable
116 if (!environment.isEmpty()) {
117 QByteArray env = qgetenv(environment);
118 if (!env.isEmpty())
119 return T(env.toInt()); // works when T is bool, int.
120 }
121
122 return fallback;
123}
124
125template<typename T>
126T qt_mac_resolveOption(const T &fallback, QWindow *window, const QByteArray &property, const QByteArray &environment)
127{
128 // check for environment variable
129 if (!environment.isEmpty()) {
130 QByteArray env = qgetenv(environment);
131 if (!env.isEmpty())
132 return T(env.toInt()); // works when T is bool, int.
133 }
134
135 // check for window property
136 if (window && !property.isNull()) {
137 QVariant windowProperty = window->property(property);
138 if (windowProperty.isValid())
139 return windowProperty.value<T>();
140 }
141
142 // return default value.
143 return fallback;
144}
145
146// https://stackoverflow.com/a/52722575/2761869
147template<class R>
148struct backwards_t {
149 R r;
150 constexpr auto begin() const { using std::rbegin; return rbegin(r); }
151 constexpr auto begin() { using std::rbegin; return rbegin(r); }
152 constexpr auto end() const { using std::rend; return rend(r); }
153 constexpr auto end() { using std::rend; return rend(r); }
154};
155template<class R>
156constexpr backwards_t<R> backwards(R&& r) { return {std::forward<R>(r)}; }
157
159
160// @compatibility_alias doesn't work with protocols
161#define QNSPanelDelegate QT_MANGLE_NAMESPACE(QNSPanelDelegate)
162
163@protocol QNSPanelDelegate
164@required
165- (void)onOkClicked;
166- (void)onCancelClicked;
167@end
168
169@interface QT_MANGLE_NAMESPACE(QNSPanelContentsWrapper) : NSView
170
171@property (nonatomic, readonly) NSButton *okButton;
172@property (nonatomic, readonly) NSButton *cancelButton;
173@property (nonatomic, readonly) NSView *panelContents; // ARC: unretained, make it weak
174@property (nonatomic, assign) NSEdgeInsets panelContentsMargins;
175
176- (instancetype)initWithPanelDelegate:(id<QNSPanelDelegate>)panelDelegate;
177- (void)dealloc;
178
179- (NSButton *)createButtonWithTitle:(QPlatformDialogHelper::StandardButton)type;
180- (void)layout;
181
182@end
183
185
186// -------------------------------------------------------------------------
187
188// Depending on the ABI of the platform, we may need to use objc_msgSendSuper_stret:
189// - http://www.sealiesoftware.com/blog/archive/2008/10/30/objc_explain_objc_msgSend_stret.html
190// - https://lists.apple.com/archives/cocoa-dev/2008/Feb/msg02338.html
191template <typename T>
192struct objc_msgsend_requires_stret
193{ static const bool value =
194#if defined(Q_PROCESSOR_X86)
195 #define PLATFORM_USES_SEND_SUPER_STRET 1
196 // Any return value larger than two registers on i386/x86_64
197 sizeof(T) > sizeof(void*) * 2;
198#elif defined(Q_PROCESSOR_ARM_32)
199 #define PLATFORM_USES_SEND_SUPER_STRET 1
200 // Any return value larger than a single register on arm
201 sizeof(T) > sizeof(void*);
202#elif defined(Q_PROCESSOR_ARM_64)
203 #define PLATFORM_USES_SEND_SUPER_STRET 0
204 false; // Stret not used on arm64
205#endif
206};
207
208template <>
209struct objc_msgsend_requires_stret<void>
210{ static const bool value = false; };
211
212template <typename ReturnType, typename... Args>
213ReturnType qt_msgSendSuper(id receiver, SEL selector, Args... args)
214{
215 static_assert(!objc_msgsend_requires_stret<ReturnType>::value,
216 "The given return type requires stret on this platform");
217
218 typedef ReturnType (*SuperFn)(objc_super *, SEL, Args...);
219 SuperFn superFn = reinterpret_cast<SuperFn>(objc_msgSendSuper);
220 objc_super sup = { receiver, [receiver superclass] };
221 return superFn(&sup, selector, args...);
222}
223
224#if PLATFORM_USES_SEND_SUPER_STRET
225template <typename ReturnType, typename... Args>
226ReturnType qt_msgSendSuper_stret(id receiver, SEL selector, Args... args)
227{
228 static_assert(objc_msgsend_requires_stret<ReturnType>::value,
229 "The given return type does not use stret on this platform");
230
231 typedef void (*SuperStretFn)(ReturnType *, objc_super *, SEL, Args...);
232 SuperStretFn superStretFn = reinterpret_cast<SuperStretFn>(objc_msgSendSuper_stret);
233
234 objc_super sup = { receiver, [receiver superclass] };
235 ReturnType ret;
236 superStretFn(&ret, &sup, selector, args...);
237 return ret;
238}
239#endif
240
241template<typename... Args>
242class QSendSuperHelper {
243public:
244 QSendSuperHelper(id receiver, SEL sel, Args... args)
245 : m_receiver(receiver), m_selector(sel), m_args(std::make_tuple(args...)), m_sent(false)
246 {
247 }
248
249 ~QSendSuperHelper()
250 {
251 if (!m_sent)
252 msgSendSuper<void>(m_args);
253 }
254
255 template <typename ReturnType>
256 operator ReturnType()
257 {
258#if defined(QT_DEBUG)
259 Method method = class_getInstanceMethod(object_getClass(m_receiver), m_selector);
260 char returnTypeEncoding[256];
261 method_getReturnType(method, returnTypeEncoding, sizeof(returnTypeEncoding));
262 NSUInteger alignedReturnTypeSize = 0;
263 NSGetSizeAndAlignment(returnTypeEncoding, nullptr, &alignedReturnTypeSize);
264 Q_ASSERT(alignedReturnTypeSize == sizeof(ReturnType));
265#endif
266 m_sent = true;
267 return msgSendSuper<ReturnType>(m_args);
268 }
269
270private:
271 template <typename ReturnType, bool V>
272 using if_requires_stret = typename std::enable_if<objc_msgsend_requires_stret<ReturnType>::value == V, ReturnType>::type;
273
274 template <typename ReturnType, int... Is>
275 if_requires_stret<ReturnType, false> msgSendSuper(std::tuple<Args...>& args, QtPrivate::IndexesList<Is...>)
276 {
277 return qt_msgSendSuper<ReturnType>(m_receiver, m_selector, std::get<Is>(args)...);
278 }
279
280#if PLATFORM_USES_SEND_SUPER_STRET
281 template <typename ReturnType, int... Is>
282 if_requires_stret<ReturnType, true> msgSendSuper(std::tuple<Args...>& args, QtPrivate::IndexesList<Is...>)
283 {
284 return qt_msgSendSuper_stret<ReturnType>(m_receiver, m_selector, std::get<Is>(args)...);
285 }
286#endif
287
288 template <typename ReturnType>
289 ReturnType msgSendSuper(std::tuple<Args...>& args)
290 {
291 return msgSendSuper<ReturnType>(args, QtPrivate::makeIndexSequence<sizeof...(Args)>{});
292 }
293
294 id m_receiver;
295 SEL m_selector;
296 std::tuple<Args...> m_args;
297 bool m_sent;
298};
299
300template<typename... Args>
301QSendSuperHelper<Args...> qt_objcDynamicSuperHelper(id receiver, SEL selector, Args... args)
302{
303 return QSendSuperHelper<Args...>(receiver, selector, args...);
304}
305
306// Same as calling super, but the super_class field resolved at runtime instead of compile time
307#define qt_objcDynamicSuper(...) qt_objcDynamicSuperHelper(self, _cmd, ##__VA_ARGS__)
308
309// -------------------------------------------------------------------------
310
311struct InputMethodQueryResult : public QHash<int, QVariant>
312{
313 operator bool() { return !isEmpty(); }
314};
315
316InputMethodQueryResult queryInputMethod(QObject *object, Qt::InputMethodQueries queries = Qt::ImEnabled);
317
318// -------------------------------------------------------------------------
319
320struct KeyEvent
321{
322 ulong timestamp = 0;
324
326 Qt::KeyboardModifiers modifiers = Qt::NoModifier;
328 bool isRepeat = false;
329
330 // Scan codes are hardware dependent codes for each key. There is no way to get these
331 // from Carbon or Cocoa, so leave it 0, as documented in QKeyEvent::nativeScanCode().
332 static const quint32 nativeScanCode = 0;
333
334 quint32 nativeVirtualKey = 0;
335 NSEventModifierFlags nativeModifiers = 0;
336
337 KeyEvent(NSEvent *nsevent);
338 bool sendWindowSystemEvent(QWindow *window) const;
339};
340
342
343// -------------------------------------------------------------------------
344
345QDebug operator<<(QDebug, const NSRange &);
347
348#endif // __OBJC__
349
350#endif //QCOCOAHELPERS_H
351
\inmodule QtCore
Definition qbytearray.h:57
int toInt(bool *ok=nullptr, int base=10) const
Returns the byte array converted to an int using base base, which is ten by default.
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:107
\inmodule QtCore
Type
This enum type defines the valid event types in Qt.
Definition qcoreevent.h:51
\inmodule QtCore
Definition qhash.h:820
\inmodule QtCore
Definition qobject.h:103
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
The QPlatformDialogHelper class allows for platform-specific customization of dialogs.
\inmodule QtCore\reentrant
Definition qpoint.h:217
\inmodule QtCore\reentrant
Definition qrect.h:484
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
\inmodule QtCore
Definition qvariant.h:65
T value() const &
Definition qvariant.h:516
bool isValid() const
Returns true if the storage type of this variant is not QMetaType::UnknownType; otherwise returns fal...
Definition qvariant.h:714
\inmodule QtGui
Definition qwindow.h:63
EGLImageKHR int int EGLuint64KHR * modifiers
QString text
rect
[4]
Combined button and popup list for selecting options.
InvokeGenSeq< GenSeq< N > > makeIndexSequence
@ ImEnabled
MouseButton
Definition qnamespace.h:56
@ Key_unknown
@ NoModifier
DropAction
Qt::MouseButtons cocoaMouseButtons2QtMouseButtons(NSInteger pressedMouseButtons)
Returns the Qt::MouseButtons that corresponds to an NSEvent.pressedMouseButtons.
NSString * qt_mac_AppKitString(NSString *table, NSString *key)
QNSView * qnsview_cast(NSView *view)
Returns the view cast to a QNSview if possible.
QEvent::Type cocoaEvent2QtMouseEvent(NSEvent *event)
Returns the QEvent::Type that corresponds to an NSEvent.type.
Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions)
QString qt_mac_applicationName()
QPointF qt_mac_flip(const QPointF &pos, const QRectF &reference)
Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum)
Returns the Qt::Button that corresponds to an NSEvent.buttonNumber.
QStringList qt_mac_NSArrayToQStringList(NSArray< NSString * > *array)
void qt_mac_transformProccessToForegroundApplication()
NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions)
Qt::DropAction qt_mac_mapNSDragOperation(NSDragOperation nsActions)
QString qt_mac_removeAmpersandEscapes(QString s)
InputMethodQueryResult queryInputMethod(QObject *object, Qt::InputMethodQueries queries)
NSDragOperation qt_mac_mapDropAction(Qt::DropAction action)
NSMutableArray< NSString * > * qt_mac_QStringListToNSMutableArray(const QStringList &list)
Qt::MouseButtons currentlyPressedMouseButtons()
Returns the Qt::MouseButtons that corresponds to an NSEvent.pressedMouseButtons.
long NSInteger
unsigned long NSUInteger
#define QT_NAMESPACE_ALIAS_OBJC_CLASS(__KLASS__)
Definition qcore_mac_p.h:58
#define Q_FORWARD_DECLARE_OBJC_CLASS(classname)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_DECLARE_LOGGING_CATEGORY(name)
return ret
GLuint64 key
GLboolean r
[2]
GLuint GLuint end
GLint reference
GLenum type
GLenum target
struct _cl_event * event
GLdouble s
[6]
Definition qopenglext.h:235
GLuint GLuint GLuint GLuint arg1
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
GLenum GLenum GLsizei void * table
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
#define QT_MANGLE_NAMESPACE(name)
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
unsigned int quint32
Definition qtypes.h:50
unsigned long ulong
Definition qtypes.h:35
const char property[13]
Definition qwizard.cpp:101
QList< int > list
[14]
QFileSelector selector
[1]
QDataStream & operator<<(QDataStream &out, const MyClass &myObj)
[4]
QVBoxLayout * layout
sem release()
aWidget window() -> setWindowTitle("New Window Title")
[2]
QQuickView * view
[0]
QJSValueList args